The best Thunderbird alternatives are K-9 Mail, eM Client and Evolution. Our crowd-sourced lists contains more than 50 apps similar to Thunderbird for Windows, Mac, Linux, Android and more. Configure Chatzilla to run as a tab. Bug #3 for this in the FAQ 'Clicking web links in the chat area will usually replace ChatZilla with the webpage. If you try to open the link in a new tab or window (either from the context menu or using a modifier key).' Can be fixed with simple CSS code to configure all links to open in a new tab within the. A summary of repository state for chatzilla.
This is a step by step tutorial on building a basic real time chat application using Flask, socket.io and gevent-socketio. All the code is available here. You can find live version of the app here.
As of Oct 8 2013, Heroku rolled out Public Beta of Websockets. The official announcement can be found here.
If you don't enable Websocket functionality on Heroku, Socket.io will fallback to XHR polling.
To enable websockets on your Heroku app, use the following command
Chatzilla Firefox Extension
Chapter 1: Getting started
I assume you know what Heroku is and you've seen Python before. Prior knowledge of Flask is a plus but given how minimalistic it is, you can just tag along.
Heroku up
First things first, let's create a shiny new appication on Heroku
I called my app 'chatzilla' and got the following output
The git part is important, let's put it to good use. Let's setup a git repository and point it towards heroku
We now have an empty git repository with a remote aliased 'heroku' pointing to the Heroku git for the project. The game is afoot.
Setup basic Flask app
Virtual environment
As every responsible Python developer, you use some kind of virtual environment manager (I personally use virtual env wrapper). Create a virtual environment named 'chatzilla' (or something else) and automatically activate it:
Virtual envs save your mental health and remaining hair, so use them.
Get all the goods using Pip
Pip is great for getting all your jazz organized. We'll be using it to install all the modules we need to make Chatzilla happen.
Please note we are using a particular version of the gunicor since later versions seem to have certain issues.
Freeze
Once Pip has installed all the modules to our previously pristine virtual environment, it's time to get a snapshot of what's installed so that when you move your app elsewhere, you can easily restore the environment
Your requirements.txt should look something like this
chatzilla.py
Let's create an entry point for the application now
Let's fill it with some Python
In it's current state, our app has none of the promised realtime awesomeness but we'll get there - one step at a time.
run_server.py
In order to run chatzilla, we'll add another python module
It looks like this:
Procfile : Flask meets Heroku
Before a much deserved refreshing beverage, let's tell Heroku how to run our application using Procfile
Inside:
This is basically us saying: could we have a web instance running gunicorn with a worker that can speak socket.io and yeah, check run_server.py for more instructions, por favor.
But will it blend?
Let's see if this works
This should launch a local dev server on your machine. If you head to http://localhost:5000/, you should be able to witness Chatzilla in all its glory.
Let's go global now
This should keep Heroku busy for a few moments. Once it's done processing the push, we can take a look at Chatzilla in the wild
Before you panic
Just in case you are stuck/confused/lazy, you can grab all the code we've produced so far here and keep following along.
Chapter 2: Sockets, por favor
Wire a namespace
We currently have a socket.io endpoint exposed to the world and we should start handling various events that will get triggered once people start using it. Head to chatzilla.py and add the following:
Also update import statements on the top of the module:
socketio function maps to the /socket.io/someotherstuff url and this is how the client side of the Chatzilla will try to reach out to the server with some urgent real time goodness. We obviously need to handle that, and we are doing it by proxying the request to ChatNamespace (which we'll create in a second).
Namespaces give us a way to manage various sub categories within a socket.io endpoint. For Chatzilla we will only be using a single such category called 'chat'. Let's look what a namespace definition might look like in our case:
ChatNamespace does not do a lot at this point - it logs connects and disconnects and that's it. Make sure you add the missing import to the chatzilla.py
Chatzilla App
Client is always right
Let's try to figure out if we can actually connect to the chat server from the client. One step at a time.
Massive redesign
Let's fix our landing page a bit. Start by bringing in templates
Populate landing.html with the following html
Now let's render the template using Flask:
Don't forget imports
Once you run foreman start
you should see a shiny new Chatzilla interface. Epic.
Wire the socket
Let's bring socket.io javascript goodness in the mix.
Let's update templates/landing.html to include socket.io
Connect to the server
With socket.io javascript in place, we can now connect to our chat instance. Update landing.html template with the following code
Refresh the page to see the popup. Hooray!
Join the chat
Once connected to the chat server, we should be able to join chat. Let's implement that. Jump back to chatzilla.py and add the following block to the ChatNamespace:
Back to the client, let's update the 'connect' event handler
Notice how return values from the on_join in the ChatNamespace are automatically propagate to the client and we can recover them in the event handler for the emit method.
Send a message
Let's add message sending functionality to the chat service. Start with the backend again
And now the client, let's automatically send a message once someone joins the chat
Broadcast
When a new message arrives to the server, we will want to send it to other people in the system. Let's get back to the ChatNamespace in chatzilla.py and add a BroadcastMixin which will help us do just that
Keeping imports happy
With BroadcastMixin attached to the ChatNamespace, we can update the on_message handler to look like this
We can now update the client to look something like this
If you now have a couple of tabs open in your browser you'll see an alert box with a greeting from Bob.
Let's deploy
Tons of users out there are looking forward to experiencing the new version of Chatzilla. Commit your changes, and push.
Before you panic
As before, you can grab the code for this chapter here
Chapter 3 : UI
Now that we have a functioning client-server communication model, let's add some UI on top of that so that people can control what data gets sent to the server + get rid of alert popups and display data more gracefully.
Move some stuff around
Let's isolate client side code in a separate module so we can stop poluting the landing page template
Let's move all the inline js from the landing template to chatzilla.js so it looks like this
The landing template should now look something like this
Add join chat UI
Let's add a little join chat form in a section between the header and the footer of the landing page
Before we wire the handlers for the form, let's grab [jquery validation plugin])(http://jqueryvalidation.org/) we can put ot good use here. Place this right after the jquery script tag.
Let's update chatzilla.js to handle form submission + validation
Let's also start organizing our socket interactions so we can easily call our chat server from various UI event handlers. Here's how this little submodule could look like (with 2 methods for now):
And as we update the rest of chatzilla.js:
Commit what you have and let's move on.
Add Send Message UI
Once the connection is established, let's hide the join form and show some kind of message composer:
Chatzilla Download
Our chatAPI module will need a new method (sendMessage):
And here's what chatzilla.js looks like now
Notice, how we are handling the message form in a similar way + we toggle visibility on both forms after joining chat.
Commit what you have and let's move on.
Add Message List UI
As any respectable Chat application out there Chatzilla needs a list of messages that people are exchanging. Let's build it.
First, let's figure out how this impacts our chatApi module. We'll have chatAPI trigger a handler once a new message is received:
And then in the bindUI, we can do the following:
chatzilla.js now looks like this
Let's get rid of the alerts by creating a container for the messages in the landing.html. After we update the section of the landing.html it looks like this
Notice that the message list is initially invisible. We'll show it once a person joins the chat (just like with the message form)
Let's update the onMessage handler so that it displays the message within the list:
Checkout the result (2+ tabs). Commit, grab a drink.
More context
Current version of Chatzilla has a number of issues. The most noticeable one is that you can't really tell who the messages you receive come from. Let's fix that.
Session
We can take advantage of session data to keep track of the message sender. Let's modify on_join handler for the ChatNamespace in chatzilla.py
This will allow to keep track of who's sending a message and we can use this data when we broadcast messages to others in the chat
Tell the client
We can now update chatzilla.js to take advantage of this additional information
Let's also make sure your own message are added to the list once sent:
Chatzilla For Linux
Commit what you have. And push what you have to heroku.
Before you panic
All the code for chapter 3 is here if you need it.
Chapter 4: More UI
The final version of the app is available here. You'll notice it's quite different from where we left in Chapter 3. All the code is available here.