aboutsummaryrefslogtreecommitdiff
blob: 11489f49e84f78471dc254085f30d55a67e35034 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# -*- coding: utf-8 -*-
# Create your views here.

from django.shortcuts import render_to_response
from django.conf import settings
from random import randint
import logging
import re

META_LANG_KEY = 'HTTP_ACCEPT_LANGUAGE'

def serve_ads(request):
	sample = _weighted_random_sample(settings.ADS_STRUCT)
	accept_langs = _build_lang_array(request)
	ads = [_trans_ad(a, accept_langs) for a in sample]
	return render_to_response('ads.html', {'ads': ads, 'MEDIA_URL': settings.MEDIA_URL,})

def _build_lang_array(request):
	accept_langs = [settings.DEFAULT_ADS_LANG]
	if META_LANG_KEY in request.META:
		accept_langs_raw = request.META[META_LANG_KEY]
		# Ignore priority for now, hopefully they are in the correct order
		# TODO: reorder per HTTP language RFC
		accept_langs = [re.sub(';q=[0-9.]+', '' ,_).strip() for _ in accept_langs_raw.split(',')]
		#accept_langs = [_.strip() for _ in accept_langs_raw.split(',')]
		#accept_langs = accept_langs_raw.split(',')
		# Handle dialects
		accept_langs = [re.sub('[-_][_-a-zA-Z0-9]+', '', lang) for lang in accept_langs if '-' in lang]

	return accept_langs

def _match_langs(accept_langs, available_langs):
	lang = settings.DEFAULT_ADS_LANG
	common_langs = set(accept_langs) & set(available_langs)
	for _ in accept_langs:
		if _ in common_langs:
			lang = _
			break
	return lang

def _trans_ad(ad, accept_langs):
	for k in settings.TRANS_KEYS:
		if k not in ad:
			continue
		if isinstance(ad[k], dict):
			lang = _match_langs(accept_langs, ad[k].keys())
			ad[k] = ad[k][lang]
	
	return ad

def _weighted_random_sample(ads):
	ads_out = []
	
	for i in xrange(settings.ADS_LENGTH):
		indices = [a['weight'] for a in ads]
		s = sum(indices)
		r = randint(0, s-1)
		cur_total = 0

		for ad_i in xrange(len(ads)):
			ad = ads[ad_i]
			cur_total += ad['weight']
			
			if r < cur_total:
				ads_out.append(ad.copy())
				ads = ads[:ad_i] + ads[ad_i + 1:]
				break
	
	ads_log_data_message = ','.join([a['name'] for a in ads_out])
	logging.info(ads_log_data_message)
	return ads_out