"""
    Analytics Middleware for Django
    Copyright (C) 2007  Will R Larson (lethain@gmail.com)

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA


    This is a fairly simple Middleware that will inject the necessary html
    in order to hook pages generated by Django with your Google Analytics
    account.

    Usage
    add a global variable ANALYTICS_ID = "myGoogleAnalyticsID" to your settings.py
    file. You may optionally add an ANALYTICS_IGNORE_ADMIN = True field to your
    settings.py if you would like for pages rendered for admin users to not
    have the Google Analytics code injected.

    The last step to enable the AnalyticsMiddleware is to then add the
    middleware to the MIDDLEWARE_CLASSES tuple within settings.py.
    The exact entry will vary on where you place the middleware,
    but if you place the analytics.py file within your django.middleware
    folder, then the entry would look like:
        'django.middleware.analytics.GoogleAnalyticsMiddleware',
    Alternatively if you placed it within a project folder, your entry
    might look like
        'myproject.analytics.GoogleAnalyticsMiddleware',
   
    The position of this entry within the MIDDLE_WARE_CLASSES
    list is not signifigant (it can be the first, the last, or
    anywhere inbetween).
"""


from django.conf import settings


class GoogleAnalyticsMiddleware(object):
    def __init__(self):
        'Constructor for GoogleAnalyticsMiddleware'
        try:
            # if id has been set in settings.py,
            # store it locally and set process_response
            # to insert the analytics code
            id = settings.ANALYTICS_ID
            self.html = self.form_analytics_string(id)

            # uncomment below to test without
            # actually sending data to Google Analytics
            #self.html = "<h2>GOOGLE_ANALYTICS_MIDDLEWARE_IS_ACTIVE</h2>"

            self.process_response = self.insert_analytics
            try:
                # check settings.py for ANALYTICS_IGNORE_ADMIN
                # if true then don't render analytics for
                # pages loaded by admins
                ignore = settings.ANALYTICS_IGNORE_ADMIN
                if ignore is True:
                    self.process_response = self.ignore_admin(
                        self.process_response)
            except AttributeError:
                pass

        except AttributeError:
            # if no id is found in settings.py,
            # then we will simply return any response
            # unaltered
            self.process_response = self.return_unaltered


    def insert_analytics(self, request, response):
        'Insert Google Analytics call into response.'
        if settings.DEBUG: return response
        content = response.content
        index = content.upper().find('</BODY>')
        if index == -1: return response
        response.content =  content[:index] +\
            self.html +\
            content[index:]
        return response


    def return_unaltered(self, request, response):
        'Return response without making any changes.'
        return response


    @staticmethod
    def ignore_admin(func):
        'Curry ignore_if_admin onto function passed as argument. '
        def ignore_if_admin(request, response):
            if request.user.is_authenticated() and request.user.is_staff:
                return response
            else:
                return func(request, response)

        return ignore_if_admin


    @staticmethod
    def form_analytics_string(id):
        'Generate html for calling Google Analytics.'
        return """
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%%3E%%3C/script%%3E"));
</script>

<script type="text/javascript">
var pageTracker = _gat._getTracker("%s");
pageTracker._initData();
pageTracker._trackPageview();
</script>
""" % ( str(id) )
