Author | Nnoduka Eruchalu |
Date | 04/04/2014 |
Website | http://noddymix.com/ |
NoddyMix is the source of the latest and greatest from the Nigerian Music Industry. Users can make and share playlists. Logged in users get the additional ability to follow friends and stay updated on friend's activities in realtime
As an added bonus users get to use native-like mobile web-apps thanks to Sencha Touch
- iOS 4+
- Android 2.3+
- Blackberry OS7+ and Playbook
- Windows Phone 8
Button | Action |
---|---|
space |
play/pause |
backspace |
mute |
up |
volume up |
down |
volume down |
left |
prev song |
right |
next song |
- Python
- MySQL
- Javascript
- HTML
- CSS
- node.js [Used for realtime feeds]
- Redis [Used for realtime feeds]
- Amazon Web Services
Module | Description |
---|---|
middleware.py |
Mobile browser detection middleware |
settings.py |
Django settings for project |
urls.py |
URL dispatcher for project |
utils.py |
Utility functions useful to multiple Django apps |
wsgi.py |
WSGI config for NoddyMix project |
apps/ |
Django apps with backend logic |
apps/account/ |
User account representation and auth. app |
apps/activity/ |
User site activity app |
apps/activity/nodejs |
Node.js module used for realtime feeds |
apps/audio/ |
Audio songs & playlists app |
apps/feedback/ |
User feedback app |
apps/relationship/ |
User relationships (followings/followers) app |
apps/search/ |
Search engine integration app |
static/ |
static files for project |
static/css/ |
Desktop CSS file |
static/img |
Desktop static images |
static/js/ |
Desktop Javascript file(s) |
static/mobile/ |
Mobile Static files using Sencha Touch (JS, CSS, HTML) |
templates/ |
Django templates used by apps |
templates/404.html |
404 page |
templates/500.html |
500 page |
templates/headfoot.html |
base template used by all templates |
templates/account/ |
templates used by account app's views |
templates/activity/ |
templates used by activity apps' views |
templates/audio/ |
templates used by audio app's views |
templates/feedback/ |
templates used by feedback app's views |
templates/relationship/ |
templates used by relationship app's views |
templates/search/ |
templates and indexes used by search app |
- django-social-auth
- django imagekit
- depends on pilkit
- depends on django-appconf
- depends on six
- django storages
- specifically S3.py which
- depends on python-boto
- specifically S3.py which
- django haystack
- mutagen
- redis-py
- jQuery
- jQuery UI
- Widgets: Slider, Sortable, Droppable
- Apprise-v2
- jQuery tipsy
- jPlayer
- Sencha Touch
3rd-party node.js modules
- socket.io:
npm install socket.io
- node-redis:
npm install redis
- node-mysql:
npm install mysql@2.0.0-alpha8
The Django project is missing the noddymix/settings_secret.py
file. A template version is included for help in setting up the sensitive information needed by the project.
The Nodejs module is also missing the noddymix/apps/activity/nodejs/config.js
file. A template version is included for help in setting up the sensitive information needed by project.
Sencha Touch is not included in this repository. You must download it from the Sencha Touch Website and add it to the noddymix/static/mobile/touch
folder.
You will also need Sencha CMD to build your application. Downlad it from the Sencha CMD Website
Navigate to the directory noddymix/static/mobile/touch
and run the command:
sencha app build production
This creates production data at noddymix/static/mobile/build/NoddyMix/production
. Navigate to this directory and you will see that there is a file called cache.appcache
.
The problem is that iPhones seem to only pick up HTML5 cache changes with .manifest
and not .appcache
. Fix this by running:
mv cache.appcache cache.manifest
Navigate to noddymix/static/js/
you see a number (>10) JS files.
To minimize the number of download requests a user's browser has to make,
I combine all JS files and gzip it, using following commands:
cat jquery-1.10.1.min.js jquery-ui-1.10.3.custom.min.js jquery.tipsy.js apprise-v2.js utils.js contextMenu.js jquery.jplayer.min.js playlist.js global.js > compressed/compiled.js
cd compressed
gzip -c compiled.js > compressed.js
Navigate to noddymix/static/css
and you see 1 CSS file. This CSS file is
simply gzip'd.
gzip.c global.css > compressed/global.css
The static images and compressed css & js are uploaded to the appropriate AWS S3 bucket. Django's settings know to pick up files from there when not in DEBUG mode.
These instructions here are what I did on my Webfaction server.
Add the following lines to ensure all requests to www.noddymix.com are redirected to noddymix.com.
The mobile web-app will make direct requests to this server (as opposed to AWS S3 bucket) for static files. So redirect those requests to the appropriate production build location.
LoadModule alias_module modules/mod_alias.so
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.noddymix\.com [NC]
RewriteRule ^(.*)$ http://noddymix.com$1 [L,R=301]
RewriteRule ^/(.+\.swf)$ http://static.noddymix.com.s3.amazonaws.com/$1 [L]
AliasMatch ^/(.+\.css|.+\.js|.+\.png|.+\.jpg|.+\.gif|.+\.json|.+\.html|.+\.manifest)$ /home/nceruchalu/webapps/noddymix/noddymix/noddymix/static/mobile/build/NoddyMix/production/$1
Addtype text/cache-manifest .appcache
AddType text/cache-manifest .manifest
Access crontab with:
crontab -e
Edit it to perform following functionality:
- Setup PATH, PYTHONPATH, NODE_PATH to be used by cron's environment
- Restart apache every 30 minutes. This ensures minimal downtime (if at all)
- Run management command to update search indexes every 45 minutes.
- Run redis and nodejs watchdog scripts every 5 minutes to ensure realtime feed is always running
- Backup database daily using configurations hidden in config file [some values redacted]
PATH=/home/nceruchalu/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:.
PYTHONPATH=/home/nceruchalu/lib/python2.7:/home/nceruchalu/pythonlibs:/home/nceruchalu/webapps/noddymix:/home/nceruchalu/webapps/noddymix/noddymix
NODE_PATH="/home/nceruchalu/lib/node_modules"
12,32,52 * * * * ~/webapps/noddymix/apache2/bin/start
*/45 * * * * /usr/local/bin/python2.7 ~/webapps/noddymix/noddymix/manage.py update_index > ~/cron/noddymix_update_index.log 2>&1
0 */4 * * * /usr/local/bin/python2.7 ~/webapps/noddymix/noddymix/manage.py rank_songs
*/5 * * * * sh ~/cron/watchdog_redis.sh > ~/cron/watchdog_redis.log 2>&1
*/5 * * * * sh ~/cron/watchdog_node.sh > ~/cron/watchdog_node.log 2>&1
0 2 * * * mysqldump --defaults-file=$HOME/db_backups/<config-filename>.cnf -u <username> <database> > $HOME/db_backups/<backups-root-filename>-`date +\%Y\%m\%d`.sql 2>> $HOME/db_backups/cron.log
The watchdog scripts are to keep the node.js and redis servers always running. These two services are needed for the realtime feed so downtime isn't acceptable.
#!/usr/bin/env bash
PIDFILE="$HOME/pid/redis.pid"
if [ -e "${PIDFILE}" ] && (ps -u $(whoami) -f | grep "[ ]$(cat ${PIDFILE})[ ]"); then
echo "Already running."
exit 99
fi
$HOME/bin/redis-server $HOME/redis/redis.conf > $HOME/cron/log/redis.log &
echo $! > "${PIDFILE}"
chmod 644 "${PIDFILE}"
#!/usr/bin/env bash
PIDFILE="$HOME/pid/node.pid"
if [ -e "${PIDFILE}" ] && (ps -u $(whoami) -f | grep "[ ]$(cat ${PIDFILE})[ ]"); then
echo "Already running."
exit 99
fi
$HOME/lib/node_modules/forever/bin/forever start -a -l $HOME/cron/log/forever.log -o $HOME/cron/log/noddymix_feed_out.log -e $HOME/cron/log/noddymix_feed_err.log --pidFile $HOME/pid/node.pid $HOME/webapps/noddymix/noddymix/noddymix/apps/activity/nodejs/feed.js
- deploying nodejs
- deploying redis
- place redis in a custom app and custom port
- keep redis running with a cron watchdog script
- more on running redis in background
- restart redis
- then use forever to keep node.js running [this fails if redis isn't up]
python manage.py runserver 0:8000 --nostatic