Toast notifications feature

Toast notifications are messages that pop up in a small dialog on the screen.

![image](https://cloud.githubusercontent.com/assets/5578984/4754823/ec3c70f6-5ac0-11e4-8b95-b1679fa8618b.png)

To get toast notifications, another user can modify a top level item that you are subscribed to. I changed the subscribe icon on the top from a 'check mark' to a 'satellite beaconing' to try and make it more obvious. Note that if you modify the object, then you do not get notifications from yourself. So I've mainly been testing this by logging in as two different users in two different browsers.

You can also get notifications if someone creates a general notification (notifications/handlers/create_general_notification). This could be used by services to tell a user a report summary or that something has finished processing.

I did not implement a change notification for Analysis results, but this would be highly desired, in my opinion, for services or any long running task. We could implement this in the future.

I made an effort to improve the notification messages to be more detailed. Instead of just the simple message:

```
rlok updated the following attributes: bucket_list
```

You will now see something like:

```
Added to bucket_list: APT
```

These detailed messages will only be visible for logged in users from the CRITs page. Users will still see vague and generic messages on email notifications if you have that set up. 

Notification filtering is restricted to those that have access to the source of a top level item. So you must have access to a specific source to view specific top level items assigned to that source. For example you will not be able to see the message "Source name added: ZEUS" if you do not have access to the ZEUS source. Other things do not have restrictions even though there may be a source, such as comments and objects.


There were two ways of implementing the polling strategy: synchronous and asynchronous. I went with the synchronous approach because we could easily fall back to the asynchronous approach if needed -- heck we could possibly implement both solutions.

The synchronous approach from the client perspective:
* Poll for changes periodically
* If notifications exist upon querying the server then they are returned
* If notifications do not exist then the client request thread is blocked until a timeout of 60 seconds or until a notification is available for that user.

The synchronous approach from the server perspective:
* Whenever a notification is created, any blocked threads that the notification is targeting from the client perspective are notified so that they are unblocked and can get the latest notification

The upside to the synchronous approach is that the notifications are very fast. The downsides to this synchronous approach is that threads are blocked. If you are using apache then there is a limit on the number of threads (256 by default?). I am not sure about the django runserver. I tried investigating a web sockets approach but they appear to be hacks on top of django so I didn't pursue it any further.

The upside to the asynchronous approach is that the threads are not blocked and not as many resources are taken up on the server side. The downside is that there could be a delay in getting notifications.


There are both user level and admin level configuration options for toast notifications. Admins can disable/enable toast notifications globally from the admin control panel (toast notifications are disabled by default). Users can change their settings from the user preferences page. There is a setting for 'sticky' or 'timeout' notifications. Sticky notifications are the default and the notifications will persist until the user acknowledges the messages. Timeout will automatically acknowledge the notifications after a specified time period.


If a client does not successfully poll a server in 5 consecutive attempts then it will give up on polling, as a throttling mechanism (e.g. user leaves CRITs tabs open overnight but login session times out).


My goal for implementing toast notifications was not to overhaul the current notifications but to build on top of it, make the changes transparent to the current notifications system, and also providing a generic framework for toast notifications -- even though I saw some shortcomings from the existing notifications. It's certainly not perfect but these details/deficiencies could be ironed out over time. For example:
* users could get flooded with notification messages, 
* users lose their notification history once they acknowledge a notification, it would be useful and probably easy to retain history by adding another "users" field to the Mongo Notification object, 
* would be useful to subscribe on other items such as when an object is assigned to a campaign or bucket list.

Something I've noticed is that the django runserver does not automatically detect code changes when you have threads blocked. So previously I would be able to make code changes without restarting the runserver. Now I need to control + c, pkill -f runserve[r] and then restart the runserver in order for new code changes to get picked up. Not sure if there is a setting for this or a workaround available. So keep this in mind if you are enabling toast notifications for now. 

You will also see many more "error: [Errno 32] Broken pipe" messages, this is due to the threads blocking and when they finally release then the client does not care about the request anymore (e.g. having navigated off the page).
How is this related to the notifications stuff?