Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/manage.py |
— | — | @@ -0,0 +1,15 @@ |
| 2 | +#!/usr/bin/python |
| 3 | + |
| 4 | +from django.core.management import execute_manager |
| 5 | +import sys |
| 6 | +sys.path.append('/home/rfaulkner/trunk/projects/') |
| 7 | + |
| 8 | +try: |
| 9 | + import settings # Assumed to be in the same directory. |
| 10 | +except ImportError: |
| 11 | + import sys |
| 12 | + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) |
| 13 | + sys.exit(1) |
| 14 | + |
| 15 | +if __name__ == "__main__": |
| 16 | + execute_manager(settings) |
Property changes on: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/manage.py |
___________________________________________________________________ |
Added: svn:executable |
1 | 17 | + * |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/campaigns/views.py |
— | — | @@ -0,0 +1,142 @@ |
| 2 | + |
| 3 | +from django.shortcuts import render_to_response |
| 4 | +from django.http import Http404 |
| 5 | +from django.shortcuts import render_to_response, get_object_or_404 |
| 6 | +from django.template import RequestContext |
| 7 | +from django.http import HttpResponseRedirect, HttpResponse |
| 8 | +from django.core.urlresolvers import reverse |
| 9 | + |
| 10 | +import sys |
| 11 | +import datetime |
| 12 | +# sys.path.append('/home/rfaulkner/trunk/projects/') |
| 13 | +# sys.path.append('/home/rfaulkner/trunk/projects/Fundraiser_Tools/classes') |
| 14 | + |
| 15 | +import os |
| 16 | +import Fundraiser_Tools.classes.Helper as Hlp |
| 17 | +import Fundraiser_Tools.classes.DataReporting as DR |
| 18 | +import Fundraiser_Tools.classes.DataLoader as DL |
| 19 | +import Fundraiser_Tools.classes.TimestampProcessor as TP |
| 20 | +import Fundraiser_Tools.settings as projSet |
| 21 | +import operator |
| 22 | + |
| 23 | + |
| 24 | +""" |
| 25 | + Index page for finding the latest camapigns. Displays a list of recent campaigns with more than k donations over the last n hours. |
| 26 | + |
| 27 | + INPUT: |
| 28 | + |
| 29 | + RETURN: |
| 30 | + |
| 31 | +""" |
| 32 | +def index(request): |
| 33 | + |
| 34 | + """ Interface with the DataLoader """ |
| 35 | + |
| 36 | + os.chdir(projSet.__project_home__ + '/Fundraiser_Tools/classes') |
| 37 | + |
| 38 | + crl = DL.CampaignReportingLoader() |
| 39 | + campaigns, all_data = crl.run_query('totals',{'metric_name':'donations','start_time':'20101230130400','end_time':'20101230144400'}) |
| 40 | + |
| 41 | + sorted_campaigns = sorted(campaigns.iteritems(), key=operator.itemgetter(1)) |
| 42 | + sorted_campaigns.reverse() |
| 43 | + |
| 44 | + new_sorted_campaigns = list() |
| 45 | + for campaign in sorted_campaigns: |
| 46 | + key = campaign[0] |
| 47 | + |
| 48 | + if campaign[1] > 50: |
| 49 | + name = all_data[key][0] |
| 50 | + if name == None: |
| 51 | + name = 'none' |
| 52 | + timestamp = TP.timestamp_from_obj(all_data[key][3], 2, 2) |
| 53 | + new_sorted_campaigns.append([campaign[0], campaign[1], name, timestamp]) |
| 54 | + |
| 55 | + sorted_campaigns = new_sorted_campaigns |
| 56 | + |
| 57 | + os.chdir(projSet.__project_home__ + '/Fundraiser_Tools/web_reporting') |
| 58 | + |
| 59 | + return render_to_response('campaigns/index.html', {'campaigns' : sorted_campaigns}) |
| 60 | + |
| 61 | + |
| 62 | + |
| 63 | + |
| 64 | +""" |
| 65 | + |
| 66 | + Use time interval views of the data to display campaign information |
| 67 | + |
| 68 | + INPUT: |
| 69 | + |
| 70 | + request |
| 71 | + utm_campaign |
| 72 | + |
| 73 | + RETURN: |
| 74 | + |
| 75 | + HttpResponse |
| 76 | + |
| 77 | +""" |
| 78 | +def show_campaigns(request, utm_campaign): |
| 79 | + |
| 80 | + """ Look 5 hrs into the past? """ |
| 81 | + start_time = '20101230130400' |
| 82 | + end_time = '20101230144400' |
| 83 | + interval = 2 |
| 84 | + |
| 85 | + os.chdir(projSet.__project_home__ + '/Fundraiser_Tools/classes') |
| 86 | + |
| 87 | + """ Estimate start/end time of campaign """ |
| 88 | + """ This generates an image for campaign views """ |
| 89 | + ir = DR.IntervalReporting(use_labels=False, font_size=20, plot_type='line', data_loader='campaign_interval', item_keys=[utm_campaign]) |
| 90 | + ir.run(start_time, end_time, interval, 'campaign', 'views', utm_campaign, []) |
| 91 | + |
| 92 | + """ search for start_time and end_time """ |
| 93 | + |
| 94 | + top_view_interval = max(ir._counts_[utm_campaign]) |
| 95 | + |
| 96 | + # print top_view_interval |
| 97 | + # print ir._counts_[utm_campaign] |
| 98 | + |
| 99 | + start_count = 0 |
| 100 | + end_count = len(ir._counts_[utm_campaign]) |
| 101 | + begin_count = False |
| 102 | + count = 0 |
| 103 | + |
| 104 | + """ Define the start time as the first interval at least80% of the maximum view interval |
| 105 | + Define the end time as the first interval following the estimated start time and less than 50% of the maximum view interval """ |
| 106 | + for i in ir._counts_[utm_campaign]: |
| 107 | + if i > (0.4 * top_view_interval) and not(begin_count): |
| 108 | + start_count = count |
| 109 | + begin_count = True |
| 110 | + |
| 111 | + if begin_count and i < (0.2 * top_view_interval) and (end_count > count): |
| 112 | + end_count = count |
| 113 | + |
| 114 | + count = count + 1 |
| 115 | + |
| 116 | + start_time_est = TP.timestamp_to_obj(start_time, 1) + datetime.timedelta(minutes=interval * start_count) |
| 117 | + end_time_est = TP.timestamp_to_obj(start_time, 1) + datetime.timedelta(minutes=interval * end_count) |
| 118 | + start_time_est = TP.timestamp_from_obj(start_time_est, 1, 2) |
| 119 | + end_time_est = TP.timestamp_from_obj(end_time_est, 1, 2) |
| 120 | + |
| 121 | + |
| 122 | + """ determine the type of test """ |
| 123 | + """ Get the banners """ |
| 124 | + test_type = Hlp.get_test_type(utm_campaign) |
| 125 | + |
| 126 | + if test_type == 'banner': |
| 127 | + """ Get the Banners -- dataloader """ |
| 128 | + crl = DL.CampaignReportingLoader() |
| 129 | + artifact_name_list = crl.run_query('banners', {'utm_campaign' : utm_campaign, 'start_time' : start_time_est, 'end_time' : end_time_est}) |
| 130 | + |
| 131 | + elif test_type == 'LP': |
| 132 | + """ Get the Landing Pages -- data loader """ |
| 133 | + crl = DL.CampaignReportingLoader() |
| 134 | + artifact_name_list = crl.run_query('lps', {'utm_campaign' : utm_campaign, 'start_time' : start_time_est, 'end_time' : end_time_est}) |
| 135 | + |
| 136 | + os.chdir(projSet.__project_home__ + '/Fundraiser_Tools/web_reporting') |
| 137 | + |
| 138 | + return render_to_response('campaigns/show_campaigns.html', {'utm_campaign' : utm_campaign, 'start_time' : start_time_est, 'end_time' : end_time_est, 'artifacts' : artifact_name_list, 'test_type' : test_type}, context_instance=RequestContext(request)) |
| 139 | + |
| 140 | + # return HttpResponseRedirect(reverse('campaigns.views.index')) |
| 141 | + |
| 142 | + """ return a form that displays estimates and allows a test to be generated """ |
| 143 | + |
\ No newline at end of file |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/campaigns/__init__.py |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/campaigns/tests.py |
— | — | @@ -0,0 +1,23 @@ |
| 2 | +""" |
| 3 | +This file demonstrates two different styles of tests (one doctest and one |
| 4 | +unittest). These will both pass when you run "manage.py test". |
| 5 | + |
| 6 | +Replace these with more appropriate tests for your application. |
| 7 | +""" |
| 8 | + |
| 9 | +from django.test import TestCase |
| 10 | + |
| 11 | +class SimpleTest(TestCase): |
| 12 | + def test_basic_addition(self): |
| 13 | + """ |
| 14 | + Tests that 1 + 1 always equals 2. |
| 15 | + """ |
| 16 | + self.failUnlessEqual(1 + 1, 2) |
| 17 | + |
| 18 | +__test__ = {"doctest": """ |
| 19 | +Another way to test that 1 + 1 is equal to 2. |
| 20 | + |
| 21 | +>>> 1 + 1 == 2 |
| 22 | +True |
| 23 | +"""} |
| 24 | + |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/campaigns/models.py |
— | — | @@ -0,0 +1,3 @@ |
| 2 | +from django.db import models |
| 3 | + |
| 4 | +# Create your models here. |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/campaigns/urls.py |
— | — | @@ -0,0 +1,7 @@ |
| 2 | +from django.conf.urls.defaults import * |
| 3 | + |
| 4 | + |
| 5 | +urlpatterns = patterns('', |
| 6 | + (r'^$', 'campaigns.views.index'), |
| 7 | + (r'^(?P<utm_campaign>[a-zA-Z0-9_]+)$', 'campaigns.views.show_campaigns'), |
| 8 | +) |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/tests/views.py |
— | — | @@ -0,0 +1,120 @@ |
| 2 | +from django.shortcuts import render_to_response |
| 3 | +from django.http import Http404 |
| 4 | +from django.shortcuts import render_to_response, get_object_or_404 |
| 5 | +from django.template import RequestContext |
| 6 | +from django.http import HttpResponseRedirect, HttpResponse |
| 7 | +from django.core.urlresolvers import reverse |
| 8 | + |
| 9 | +import sys |
| 10 | +# sys.path.append('/home/rfaulkner/trunk/projects/') |
| 11 | +# sys.path.append('/home/rfaulkner/trunk/projects/Fundraiser_Tools/classes') |
| 12 | + |
| 13 | +import math |
| 14 | +import os |
| 15 | + |
| 16 | +import Fundraiser_Tools.classes.Helper as Hlp |
| 17 | +import Fundraiser_Tools.classes.DataLoader as DL |
| 18 | +import Fundraiser_Tools.classes.TimestampProcessor as TP |
| 19 | +import Fundraiser_Tools.settings as projSet |
| 20 | +import Fundraiser_Tools.build_report as br |
| 21 | +import operator |
| 22 | + |
| 23 | + |
| 24 | +""" |
| 25 | + <description> |
| 26 | + |
| 27 | + INPUT: |
| 28 | + |
| 29 | + RETURN: |
| 30 | + |
| 31 | +""" |
| 32 | +def index(request): |
| 33 | + return render_to_response('tests/index.html', context_instance=RequestContext(request)) |
| 34 | + |
| 35 | +""" |
| 36 | + <description> |
| 37 | + |
| 38 | + INPUT: |
| 39 | + |
| 40 | + RETURN: |
| 41 | + |
| 42 | +""" |
| 43 | +def test(request): |
| 44 | + |
| 45 | + """ check where the request came from """ |
| 46 | + """ redirect based on origin if there is an error """ |
| 47 | + """ check post data """ |
| 48 | + |
| 49 | + try: |
| 50 | + |
| 51 | + test_name_var = request.POST['test_name'] |
| 52 | + utm_campaign_var = request.POST['utm_campaign'] |
| 53 | + start_time_var = request.POST['start_time'] |
| 54 | + end_time_var = request.POST['end_time'] |
| 55 | + test_type = request.POST['test_type'] |
| 56 | + |
| 57 | + labels = request.POST['artifacts'][1:-1].split(',') |
| 58 | + label_dict = dict() |
| 59 | + |
| 60 | + for i in range(len(labels)): |
| 61 | + label = labels[i].split('\'')[1] |
| 62 | + label = label.strip() |
| 63 | + label_dict[label] = label |
| 64 | + |
| 65 | + except: |
| 66 | + |
| 67 | + return HttpResponseRedirect(reverse('tests.views.index')) |
| 68 | + # pass |
| 69 | + |
| 70 | + os.chdir(projSet.__project_home__ + '/Fundraiser_Tools/classes') |
| 71 | + |
| 72 | + """ Execute Report """ |
| 73 | + |
| 74 | + # Build a test interval - use the entire test period |
| 75 | + start_time_obj = TP.timestamp_to_obj(start_time_var, 1) |
| 76 | + end_time_obj = TP.timestamp_to_obj(end_time_var, 1) |
| 77 | + time_diff = end_time_obj - start_time_obj |
| 78 | + time_diff_min = time_diff.seconds / 60.0 |
| 79 | + test_interval = int(math.floor(time_diff_min / 2)) # 2 is the interval |
| 80 | + |
| 81 | + |
| 82 | + |
| 83 | + os.chdir(projSet.__project_home__ + '/Fundraiser_Tools/web_reporting') |
| 84 | + |
| 85 | + metric_names = Hlp.get_test_type_metrics(test_type) |
| 86 | + |
| 87 | + if test_type == 'banner': |
| 88 | + |
| 89 | + winner_dpi, percent_win_dpi, conf_dpi, winner_api, percent_win_api, conf_api = br.auto_gen(test_name=test_name_var, start_time_var, end_time_var, utm_campaign_var, label_dict, 2, test_interval) |
| 90 | + |
| 91 | + html = render_to_response('tests/results.html', {'winner' : winner_dpi, 'percent_win_dpi' : '%.2f' % percent_win_dpi, 'percent_win_api' : '%.2f' % percent_win_api, 'conf_dpi' : conf_dpi, 'conf_api' : conf_api, 'utm_campaign' : utm_campaign_var, \ |
| 92 | + 'metric_names' : metric_names}) |
| 93 | + elif test_type == 'LP': |
| 94 | + |
| 95 | + winner_dpi, percent_win_dpi, conf_dpi, winner_api, percent_win_api, conf_api = br.auto_gen(test_name=test_name_var, start_time_var, end_time_var, utm_campaign_var, label_dict, 2, test_interval) |
| 96 | + |
| 97 | + html = render_to_response('tests/results.html', {'winner' : winner_dpi, 'percent_win_dpi' : '%.2f' % percent_win_dpi, 'percent_win_api' : '%.2f' % percent_win_api, 'conf_dpi' : conf_dpi, 'conf_api' : conf_api, 'utm_campaign' : utm_campaign_var, \ |
| 98 | + 'metric_names' : metric_names}) |
| 99 | + |
| 100 | + """ Write to test table !! MODIFY -- handle updates !! """ |
| 101 | + |
| 102 | + ttl = DL.TestTableLoader() |
| 103 | + |
| 104 | + """ Format the html string """ |
| 105 | + html_string = html.__str__() |
| 106 | + html_string = html_string.replace('"', '\\"') |
| 107 | + html_string = Hlp.stringify(html_string) |
| 108 | + |
| 109 | + html_string_parts = html_string.split() |
| 110 | + html_string = '' |
| 111 | + for i in html_string_parts: |
| 112 | + html_string = html_string + i |
| 113 | + |
| 114 | + if ttl.record_exists(utm_campaign=utm_campaign_var): |
| 115 | + ttl.update_test_row(test_name=test_name_var,utm_campaign=utm_campaign_var,start_time=start_time_var,end_time=end_time_var,html_report=html_string) |
| 116 | + else: |
| 117 | + ttl.insert_row(test_name=test_name_var,utm_campaign=utm_campaign_var,start_time=start_time_var,end_time=end_time_var,html_report=html_string) |
| 118 | + |
| 119 | + return html |
| 120 | + |
| 121 | + |
\ No newline at end of file |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/tests/__init__.py |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/tests/tests.py |
— | — | @@ -0,0 +1,23 @@ |
| 2 | +""" |
| 3 | +This file demonstrates two different styles of tests (one doctest and one |
| 4 | +unittest). These will both pass when you run "manage.py test". |
| 5 | + |
| 6 | +Replace these with more appropriate tests for your application. |
| 7 | +""" |
| 8 | + |
| 9 | +from django.test import TestCase |
| 10 | + |
| 11 | +class SimpleTest(TestCase): |
| 12 | + def test_basic_addition(self): |
| 13 | + """ |
| 14 | + Tests that 1 + 1 always equals 2. |
| 15 | + """ |
| 16 | + self.failUnlessEqual(1 + 1, 2) |
| 17 | + |
| 18 | +__test__ = {"doctest": """ |
| 19 | +Another way to test that 1 + 1 is equal to 2. |
| 20 | + |
| 21 | +>>> 1 + 1 == 2 |
| 22 | +True |
| 23 | +"""} |
| 24 | + |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/tests/models.py |
— | — | @@ -0,0 +1,3 @@ |
| 2 | +from django.db import models |
| 3 | + |
| 4 | +# Create your models here. |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/tests/urls.py |
— | — | @@ -0,0 +1,7 @@ |
| 2 | +from django.conf.urls.defaults import * |
| 3 | + |
| 4 | + |
| 5 | +urlpatterns = patterns('', |
| 6 | + (r'^$', 'tests.views.index'), |
| 7 | + (r'^build_test$', 'tests.views.test') |
| 8 | +) |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/views.py |
— | — | @@ -0,0 +1,16 @@ |
| 2 | +# Create your views here. |
| 3 | +from django.shortcuts import render_to_response |
| 4 | +from django.http import Http404 |
| 5 | +from django.shortcuts import render_to_response, get_object_or_404 |
| 6 | +from django.template import RequestContext |
| 7 | +from django.http import HttpResponseRedirect, HttpResponse |
| 8 | +from django.core.urlresolvers import reverse |
| 9 | + |
| 10 | + |
| 11 | + |
| 12 | +def index(request): |
| 13 | + return render_to_response('index.html') |
| 14 | + |
| 15 | + |
| 16 | + |
| 17 | + |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/__init__.py |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/settings.py |
— | — | @@ -0,0 +1,101 @@ |
| 2 | +# Django settings for mysite project. |
| 3 | + |
| 4 | +DEBUG = True |
| 5 | +TEMPLATE_DEBUG = DEBUG |
| 6 | + |
| 7 | +ADMINS = ( |
| 8 | + ('Ryan Faulkner', 'bobs.ur.uncle@gmail.com') |
| 9 | + # ('Your Name', 'your_email@domain.com'), |
| 10 | +) |
| 11 | + |
| 12 | +MANAGERS = ADMINS |
| 13 | + |
| 14 | +DATABASES = { |
| 15 | + 'default': { |
| 16 | + 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. |
| 17 | + 'NAME': 'web_reporting', # Or path to database file if using sqlite3. |
| 18 | + 'USER': 'root', # Not used with sqlite3. |
| 19 | + 'PASSWORD': 'baggin5', # Not used with sqlite3. |
| 20 | + 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. |
| 21 | + 'PORT': '', # Set to empty string for default. Not used with sqlite3. |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +# Local time zone for this installation. Choices can be found here: |
| 26 | +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name |
| 27 | +# although not all choices may be available on all operating systems. |
| 28 | +# On Unix systems, a value of None will cause Django to use the same |
| 29 | +# timezone as the operating system. |
| 30 | +# If running in a Windows environment this must be set to the same as your |
| 31 | +# system time zone. |
| 32 | +TIME_ZONE = 'America/Chicago' |
| 33 | + |
| 34 | +# Language code for this installation. All choices can be found here: |
| 35 | +# http://www.i18nguy.com/unicode/language-identifiers.html |
| 36 | +LANGUAGE_CODE = 'en-us' |
| 37 | + |
| 38 | +SITE_ID = 1 |
| 39 | + |
| 40 | +# If you set this to False, Django will make some optimizations so as not |
| 41 | +# to load the internationalization machinery. |
| 42 | +USE_I18N = True |
| 43 | + |
| 44 | +# If you set this to False, Django will not format dates, numbers and |
| 45 | +# calendars according to the current locale |
| 46 | +USE_L10N = True |
| 47 | + |
| 48 | +# Absolute path to the directory that holds media. |
| 49 | +# Example: "/home/media/media.lawrence.com/" |
| 50 | +MEDIA_ROOT = '/home/rfaulkner/trunk/projects/Fundraiser_Tools/web_reporting/media' |
| 51 | + |
| 52 | +# URL that handles the media served from MEDIA_ROOT. Make sure to use a |
| 53 | +# trailing slash if there is a path component (optional in other cases). |
| 54 | +# Examples: "http://media.lawrence.com", "http://example.com/media/" |
| 55 | +MEDIA_URL = 'http://localhost:8000/media/' |
| 56 | + |
| 57 | + |
| 58 | +# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a |
| 59 | +# trailing slash. |
| 60 | +# Examples: "http://foo.com/media/", "/media/". |
| 61 | +ADMIN_MEDIA_PREFIX = '/media/' |
| 62 | + |
| 63 | +# Make this unique, and don't share it with anybody. |
| 64 | +SECRET_KEY = '+#la#_bbixg#f=o!5x=_^6cl$qs(t!5$ca@_0c#sfu!48-ji%2' |
| 65 | + |
| 66 | +# List of callables that know how to import templates from various sources. |
| 67 | +TEMPLATE_LOADERS = ( |
| 68 | + 'django.template.loaders.filesystem.Loader', |
| 69 | + 'django.template.loaders.app_directories.Loader', |
| 70 | +# 'django.template.loaders.eggs.Loader', |
| 71 | +) |
| 72 | + |
| 73 | +MIDDLEWARE_CLASSES = ( |
| 74 | + 'django.middleware.common.CommonMiddleware', |
| 75 | + 'django.contrib.sessions.middleware.SessionMiddleware', |
| 76 | + 'django.middleware.csrf.CsrfViewMiddleware', |
| 77 | + 'django.contrib.auth.middleware.AuthenticationMiddleware', |
| 78 | + 'django.contrib.messages.middleware.MessageMiddleware', |
| 79 | +) |
| 80 | + |
| 81 | +ROOT_URLCONF = 'web_reporting.urls' |
| 82 | + |
| 83 | +TEMPLATE_DIRS = ( |
| 84 | + "/home/rfaulkner/trunk/projects/Fundraiser_Tools/web_reporting/templates", |
| 85 | + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". |
| 86 | + # Always use forward slashes, even on Windows. |
| 87 | + # Don't forget to use absolute paths, not relative paths. |
| 88 | +) |
| 89 | + |
| 90 | +INSTALLED_APPS = ( |
| 91 | + 'django.contrib.auth', |
| 92 | + 'django.contrib.contenttypes', |
| 93 | + 'django.contrib.sessions', |
| 94 | + 'django.contrib.sites', |
| 95 | + 'django.contrib.messages', |
| 96 | + 'campaigns', |
| 97 | + 'tests', |
| 98 | + # Uncomment the next line to enable the admin: |
| 99 | + 'django.contrib.admin', |
| 100 | + # Uncomment the next line to enable admin documentation: |
| 101 | + 'django.contrib.admindocs', |
| 102 | +) |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/models.py |
— | — | @@ -0,0 +1,14 @@ |
| 2 | +class Reporter(models.Model): |
| 3 | + full_name = models.CharField(max_length=70) |
| 4 | + |
| 5 | + def __unicode__(self): |
| 6 | + return self.full_name |
| 7 | + |
| 8 | +class Article(models.Model): |
| 9 | + pub_date = models.DateTimeField() |
| 10 | + headline = models.CharField(max_length=200) |
| 11 | + content = models.TextField() |
| 12 | + reporter = models.ForeignKey(Reporter) |
| 13 | + |
| 14 | + def __unicode__(self): |
| 15 | + return self.headline |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/urls.py |
— | — | @@ -0,0 +1,12 @@ |
| 2 | +# This also imports the include function |
| 3 | +from django.conf.urls.defaults import * |
| 4 | + |
| 5 | +from django.contrib import admin |
| 6 | +admin.autodiscover() |
| 7 | + |
| 8 | +urlpatterns = patterns('', |
| 9 | + (r'^$', 'views.index'), |
| 10 | + (r'^campaigns/', include('campaigns.urls')), |
| 11 | + (r'^tests/', include('tests.urls')), |
| 12 | + (r'^admin/', include(admin.site.urls)), |
| 13 | +) |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/templates/campaigns/find_campaigns.html |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/templates/campaigns/show_campaigns.html |
— | — | @@ -0,0 +1,48 @@ |
| 2 | + |
| 3 | +<html> |
| 4 | +<head><title>Big Ass Reportin'</title></head> |
| 5 | +<body> |
| 6 | + |
| 7 | +<u><h1>{{ utm_campaign }} -- Minutely Breakdown of Campaign Views:</h1></u><br> |
| 8 | + |
| 9 | +<OBJECT WIDTH="1000" HEIGHT="600" data="../media/{{ utm_campaign }}_campaign_views.png" type="image/png"> |
| 10 | +<p>Total views broken out of minutely intervals for the given period.</p></OBJECT> |
| 11 | + |
| 12 | + |
| 13 | +This is a <u><b>{{ test_type }}</u></b> test with the following artifacts: |
| 14 | + |
| 15 | +{% if artifacts %} |
| 16 | + <ul> |
| 17 | + {% for name in artifacts %} |
| 18 | + <li>{{ name }}</li> |
| 19 | + {% endfor %} |
| 20 | + </ul> |
| 21 | +{% else %} |
| 22 | + <p>No artifacts found for this campaign.</p> |
| 23 | +{% endif %} |
| 24 | + |
| 25 | + |
| 26 | +<h3>Test this campaign?</h3> |
| 27 | +<!-- Test Form --> |
| 28 | +<form action="/tests/build_test" method="post"> |
| 29 | +{% csrf_token %} |
| 30 | +<input type="hidden" name="utm_campaign" value="{{ utm_campaign }}"> |
| 31 | +<input type="hidden" name="artifacts" value="{{ artifacts }}"> |
| 32 | +<input type="hidden" name="test_type" value="{{ test_type }}"> |
| 33 | +<label for="test_name"> |
| 34 | +<pre>TEST NAME: </pre> |
| 35 | +</label> |
| 36 | + <input type="text" name="test_name" /> |
| 37 | +<br/> |
| 38 | +<label for="start_time"> |
| 39 | +<pre>START TIMESTAMP: </pre> |
| 40 | +</label> |
| 41 | + <input type="text" name="start_time" value="{{ start_time }}"/> |
| 42 | +<br/> |
| 43 | +<label for="end_time"> |
| 44 | +<pre>END TIMESTAMP: </pre> |
| 45 | +</label> |
| 46 | +<input type="text" name="end_time" value="{{ end_time }}"/> |
| 47 | +<br><br> |
| 48 | +<input type="submit" value="Test" /> |
| 49 | +</form> |
\ No newline at end of file |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/templates/campaigns/report_on_campaign.html |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/templates/campaigns/index.html |
— | — | @@ -0,0 +1,16 @@ |
| 2 | + |
| 3 | +<html> |
| 4 | +<head><title>Big Ass Reportin'</title></head> |
| 5 | +<body> |
| 6 | + |
| 7 | +<h1>Choose a Campaign:</h1><br> |
| 8 | +<u><h3>Campaign, Donations (>50) </h1></u><br> |
| 9 | +{% if campaigns %} |
| 10 | + <ul> |
| 11 | + {% for c in campaigns %} |
| 12 | + <li>{{ c.2 }} , {{ c.3 }}, <a href="https://www.mediawiki.org/campaigns/{{ c.0 }}">{{ c.0 }}</a> , {{ c.1 }}</li><br> |
| 13 | + {% endfor %} |
| 14 | + </ul> |
| 15 | +{% else %} |
| 16 | + <p>No campaigns are available.</p> |
| 17 | +{% endif %} |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/templates/tests/results.html |
— | — | @@ -0,0 +1,29 @@ |
| 2 | + |
| 3 | +<!-- May have this dependent on test type as well --> |
| 4 | + |
| 5 | +<html> |
| 6 | +<head><title>Big Ass Reportin'</title></head> |
| 7 | +<body> |
| 8 | + |
| 9 | +<h3><u>Confidence Reporting</u></h3> |
| 10 | +<u>The winning banner is <b>{{ winner }}</b>.</u><br><br> |
| 11 | +{% if winner != 'inconclusive' %} |
| 12 | + The {{ winner_dpi }} had a {{ percent_win_dpi }}% increase in donations / impression on average. {{ conf_dpi }}<br> |
| 13 | + The {{ winner_api }} had a {{ percent_win_api }}% increase in amount50 / impression on average. {{ conf_api }}<br> |
| 14 | +{% endif %} |
| 15 | + |
| 16 | +<br> |
| 17 | + |
| 18 | +<u><h1>{{ utm_campaign }} -- Test Results:</h1></u><br> |
| 19 | + |
| 20 | +{% for m in metric_names %} |
| 21 | + <OBJECT WIDTH="1000" HEIGHT="600" data="{{ utm_campaign }}_banner_{{ m }}.png" type="image/png"><p>Measured minutely {{ m }}.</p></OBJECT><br> |
| 22 | +{% endfor %} |
| 23 | + |
| 24 | +<OBJECT WIDTH="1000" HEIGHT="600" data="{{ utm_campaign }}_campaign_views.png" type="image/png"><p>Campaign views / minute.</p></OBJECT><br> |
| 25 | +<OBJECT WIDTH="1000" HEIGHT="600" data="{{ utm_campaign }}_campaign_donations.png" type="image/png"><p>Campaign donations / minute.</p></OBJECT><br> |
| 26 | + |
| 27 | +<h3><u>Confidence Reporting</u></h3> |
| 28 | + |
| 29 | +<OBJECT WIDTH="1000" HEIGHT="600" data="{{ utm_campaign }}_conf_don_per_imp.png" type="image/png"><p>Student's T model, donations / impression.</p></OBJECT><br> |
| 30 | +<OBJECT WIDTH="1000" HEIGHT="600" data="{{ utm_campaign }}_conf_amt50_per_imp.png" type="image/png"><p>Student's T model, amount50 / impression.</p></OBJECT><br> |
\ No newline at end of file |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/templates/tests/index.html |
— | — | @@ -0,0 +1,31 @@ |
| 2 | + |
| 3 | +<html> |
| 4 | +<head><title>Big Ass Reportin'</title></head> |
| 5 | +<body> |
| 6 | + |
| 7 | +<h1>Enter a Campaign:</h1> |
| 8 | + |
| 9 | + |
| 10 | +<form action="/tests/build_test" method="post"> |
| 11 | +{% csrf_token %} |
| 12 | +<label for="utm_campaign"> |
| 13 | +<pre>UTM CAMPAIGN: </pre> |
| 14 | +</label> |
| 15 | +<input type="text" name="utm_campaign" /> |
| 16 | +<br/> |
| 17 | +<label for="start_time"> |
| 18 | +<pre>START TIMESTAMP: </pre> |
| 19 | +</label> |
| 20 | + <input type="text" name="start_time" /> |
| 21 | +<br/> |
| 22 | +<label for="end_time"> |
| 23 | +<pre>END TIMESTAMP: </pre> |
| 24 | +</label> |
| 25 | +<input type="text" name="end_time" /> |
| 26 | +<br/> |
| 27 | + |
| 28 | +<input type="submit" value="Test" /> |
| 29 | +</form> |
| 30 | + |
| 31 | +</body> |
| 32 | +</html> |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/templates/admin/base_site.html |
— | — | @@ -0,0 +1,10 @@ |
| 2 | +{% extends "admin/base.html" %} |
| 3 | +{% load i18n %} |
| 4 | + |
| 5 | +{% block title %}{{ title }} | {% trans 'Django Poll Test Project admin' %}{% endblock %} |
| 6 | + |
| 7 | +{% block branding %} |
| 8 | +<h1 id="site-name">{% trans 'Poll Project administration' %}</h1> |
| 9 | +{% endblock %} |
| 10 | + |
| 11 | +{% block nav-global %}{% endblock %} |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/templates/admin/base_site_proto.html |
— | — | @@ -0,0 +1 @@ |
| 2 | +link /usr/share/pyshared/django/contrib/admin/templates/admin/base_site.html |
\ No newline at end of file |
Property changes on: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/templates/admin/base_site_proto.html |
___________________________________________________________________ |
Added: svn:special |
1 | 3 | + * |
Index: trunk/fundraiser-statistics/fundraiser-scripts/web_reporting/templates/index.html |
— | — | @@ -0,0 +1,13 @@ |
| 2 | + |
| 3 | +<html> |
| 4 | +<head><title>Big Ass Reportin'</title></head> |
| 5 | + |
| 6 | +<body> |
| 7 | +<h1><u>Big Ass Reportin'</u></h1> |
| 8 | + |
| 9 | +<a href="https://www.mediawiki.org/campaigns/">Latest Campaigns</a><br><br> |
| 10 | + |
| 11 | +<a href="https://www.mediawiki.org/tests/">Build a Test</a> |
| 12 | + |
| 13 | +</body> |
| 14 | +</html> |
\ No newline at end of file |