web/hdalab/views/ajax.py
author ymh <ymh.work@gmail.com>
Thu, 16 Feb 2012 21:48:40 +0100
changeset 119 e3ebe3545f72
child 122 fde8335a037c
permissions -rw-r--r--
first implementation of django version. Kind of work but need optimisation. Will do them after update from raphael

# -*- coding: utf-8 -*-
'''
Created on Jan 31, 2012

@author: ymh
'''
from django.conf import settings
from django.db import connection
from django.db.models import Q, Count, Sum
from django.http import HttpResponse
from hdabo.models import Tag, Datasheet, TaggedSheet
from hdalab.models import TagLinks, HdaSession, CountryCode, TagYears
import django.utils.simplejson as json
import hmac
import uuid

def taginfo(request):
    label = request.GET.get('label', None)
    
    resobj = {'requested_label' : label}
        
    resobj["content_count"] = Datasheet.objects.filter(taggedsheet__tag__label__iexact = label).distinct().count()
    
    res = Tag.objects.select_related('dbpedia_fields').filter(label__iexact = label).order_by('-dbpedia_uri')[0:1]
    if len(res) == 1:
        restag = res.get()
        resobj["dbpedia_uri"] = restag.dbpedia_uri
        if resobj["dbpedia_uri"] is not None and restag.dbpedia_fields is not None:
            dbfield = restag.dbpedia_fields
            resobj["abstract"] = dbfield.abstract
            resobj["dbpedia_label"] = dbfield.label
            resobj["thumbnail"] = dbfield.thumbnail
    res = Tag.objects.filter(label__iexact = label).order_by('-wikipedia_url')[0:1]
    if len(res) == 1:
        resobj["wikipedia_url"] = res.get().wikipedia_url
        
    resobj["links"] = [{'subject':tl.subject.label, 'object':tl.object.label} for tl in TagLinks.objects.select_related().filter(Q(subject__label__iexact = label) | Q(object__label__iexact = label))]

    return HttpResponse(content=json.dumps(resobj), mimetype='application/json')


def sessioninfo(request):
    
    data = json.loads(request.GET.get('data', "{}"))
    write = False
    
    if 'sessionid' in request.GET:
        request.session['sessionid'] = request.GET['sessionid']
    if 'sessionkey' in request.GET:
        request.session['sessionkey'] = request.GET['sessionkey']
        
    if 'sessionid' in request.session:
        sessionid = request.session['sessionid']
        
        if HdaSession.objects.filter(sessionid=sessionid).count() == 1:
            sessionkey = request.session.get('sessionkey',None)
            hm = hmac.new(settings.SECRET_KEY, sessionid)
            if hm.hexdigest() == sessionkey:
                write = True            
        else:
            del request.session['sessionid']
        
    if 'sessionid' not in request.session:
        sessionid = unicode(uuid.uuid1())
        HdaSession.objects.create(sessionid=sessionid, data=json.dumps({}))
        write = True
        request.session['sessionid'] = sessionid
        request.session['sessionkey'] = hmac.new(settings.SECRET_KEY, sessionid).hexdigest()
        
    if write and data:
        HdaSession.objects.filter(sessionid=sessionid).update(data=json.dumps(data))
    else:
        data = HdaSession.objects.get(sessionid=sessionid).data
        data = json.loads(data) if data else {}           
         
    resobj = {'data': data, "write_allowed" : write, "sessionid": sessionid }
    if write:
        resobj['sessionkey'] = request.session['sessionkey']
        
    return HttpResponse(content=json.dumps(resobj), mimetype='application/json')


def tagsearch(request):
    
    q = request.GET.get('term',None)
    qs = Tag.objects.filter(label__icontains = q) if q else Tag.objects.all()        
    res = qs.annotate(nb=Count('datasheet')).order_by('-nb')[:20]
    
    return HttpResponse(content=json.dumps([{'label':t.label,'nb':t.nb} for t in res]), mimetype='application/json')


def filter(request):
    periode = request.GET.get('period',None)
    label = request.GET.get('label', None)
    contentlist = request.GET.get('contentlist', None)
    max_tag_order = request.GET.get('mto', 12)
    content_count = request.GET.get('contentcount', 12)
    tag_count = request.GET.get('tagcount', 30)
    cont_count = 0;
    contenus = {}


    if label or periode or contentlist :
        
        qs = Datasheet.objects.filter(validated=True)
        
        #$globalsql = "SELECT id, title, description, url FROM hdabo_datasheet E";

        globalids = []
        #$globalfilters = array();
        
        if periode:
            years = periode.split(",")
            start_year = int(years[0])
            end_year = int(years[0:2][-1])
            delta = max(1, (end_year-start_year)/2)
            minstart = start_year - delta;
            maxend = end_year + delta;
            
            tagqs = Tag.objects.filter(years__end_year__gte = start_year, 
                                       years__start_year__lte = end_year,
                                       years__end_year__lte = maxend,
                                       years__start_year__gte = minstart)
            
            globalids += [t.id for t in tagqs]
            
            qs = qs.filter(taggedsheet__tag__in = tagqs) 
            
        if label:
            for txtlbl in label.split(","):
                taglblqs = Tag.objects.filter(label__iexact = txtlbl)
                globalids += [t.id for t in taglblqs if t.id not in globalids]
                qs = qs.filter(taggedsheet__tag__in = taglblqs)

        if label or periode:
            qs = qs.filter(taggedsheet__order__lte = max_tag_order)

        if contentlist:
            qs = qs.filter(id__in = contentlist.split(","))
        
        if contentlist is None:
            qs = qs.order_by('?')
        
        
        for content in qs:
            cont_count += 1
            contenus[content.id] = {'score' : 0, 'tags' : [], 'id':content.id, 'title': content.title, 'description': content.description, 'url': content.url}


        countries = dict([ (cc.label, {'isocode':cc.isocode, 'score':0}) for cc in CountryCode.objects.all() ])
        disciplines = dict([ (d.label, {'label':d.label, 'score':0}) for d in Tag.objects.filter(category__label = "Discipline artistique")])
        
        tags = {}
        
        contentids = contenus.keys()
        qs = TaggedSheet.objects.select_related('tag').filter(datasheet__in = contentids, order__lte = max_tag_order).order_by('order')
        for ts in qs:
            match_tag = ts.tag.id in globalids
            contenus[ts.datasheet.id]['tags'].append({'id': ts.tag.id, 'label':ts.tag.label, 'order':ts.order, 'match': match_tag})
            tagscore = 2*max_tag_order - ts.order
            if ts.tag.id not in tags:
                tags[ts.tag.id] = {'id':ts.tag.id,'label':ts.tag.label, 'score':0}
            tags[ts.tag.id]['score'] += tagscore
            if match_tag:
                contenus[ts.datasheet.id]['score'] += tagscore
                tags[ts.tag.id]['match'] = True
            if ts.tag.label in countries:
                countries[ts.tag.label]['score'] += tagscore
            if ts.tag.label in disciplines:
                disciplines[ts.tag.label]['score'] += tagscore

        content_count = content_count if not contentlist else len(contenus)
        contenus = sorted(contenus.values(),key=lambda e: e.get('score', 0))[0:content_count]
        countries = countries.values()
        tags = sorted(tags.values(), key=lambda e: e.get('score', 0))[0:tag_count]
        disciplines = sorted(disciplines.values(), key=lambda e: e.get('score', 0))[0:10]
        years = {}
        if contentids:
            qs = TagYears.objects.values('start_year', 'end_year').annotate(order_count=Count('tag__taggedsheet'), order_sum=Sum("tag__taggedsheet__order")).filter(tag__taggedsheet__order__lte=max_tag_order, tag__taggedsheet__datasheet__in = contentids)
            for ty in qs:
                for year in range(ty['start_year'], ty['end_year']):
                    years[year] = (2*max_tag_order*ty['order_count']-ty['order_sum'])/(ty['end_year']-ty['start_year']) + years[year] if year in years else 0
#        $rq = pg_query("SELECT U.start_year, U.end_year, SUM(".(2*$max_tag_order)." - V.order)/(U.end_year + 1 - U.start_year) score FROM hdaviz_years U, hdabo_taggedsheet V WHERE U.tag_id = V.tag_id AND V.order <= $max_tag_order AND V.datasheet_id IN ($contentids) GROUP BY U.start_year, U.end_year");
#        while($ligne = pg_fetch_row($rq)) {
#            foreach(range($ligne[0], $ligne[1]) as $year) {
#                $years[$year] = $ligne[2] + ( isset($years[$year]) ? $years[$year] : 0 );

    else:
        
        for ds in Datasheet.objects.order_by("?")[:content_count]:
            contenus[ds.id] = {'id':ds.id, 'title':ds.title, 'description':ds.description, 'url':ds.url, 'tags':[]}
        cont_count = Datasheet.objects.count()
        
        qs = TaggedSheet.objects.select_related('tag','datasheet').filter(datasheet__id__in = contenus.keys(), order__lte = max_tag_order).order_by("order").only('order','tag__label','tag__id','datasheet__id')
        for ts in qs:
            contenus[ts.datasheet.id]['tags'].append({'id': ts.tag.id, 'label':ts.tag.label, 'order':ts.order})
        contenus = contenus.values()

        cursor = connection.cursor() #@UndefinedVariable
        try:
            cursor.execute("select t.id, t.label, sum(2*%s-ts.order) as score from hdabo_tag as t join hdabo_taggedsheet as ts on t.id = ts.tag_id where ts.order < %s group by t.id, t.label order by score limit %s",[max_tag_order, max_tag_order, tag_count])
            tags = [{'id': t[0], 'label':t[1], 'score':t[2]} for t in cursor.fetchall()]
            #tags = sorted([{'id':tag.id,'label':tag.label,'score':2*max_tag_order*tag.count_score - tag.sum_score} for tag in qs], key=lambda t:t['score'])[:tag_count]                    
        finally:
            cursor.close()
        cursor = connection.cursor() #@UndefinedVariable
        try:
            cursor.execute("select c.isocode as isocode, sum(2*%s-ts.order) as score from hdabo_tag as t join hdabo_taggedsheet as ts on t.id = ts.tag_id join hdalab_countrycode as c on t.label = c.label group by c.isocode", [max_tag_order])
            countries = [{'isocode': r[0], 'score':r[1]} for r in cursor.fetchall()]
            
        finally:
            cursor.close()

        qs = Tag.objects.annotate(count_score=Count('taggedsheet'),sum_score=Sum('taggedsheet__order')).filter(taggedsheet__order__lte = max_tag_order, category__label__iexact = u"Discipline")
        disciplines = sorted([{'label':tag.label,'score':2*max_tag_order*tag.count_score - tag.sum_score} for tag in qs], key=lambda t:t.score, reverse=True)[:10]

        years = {}
        qs = TagYears.objects.values('start_year', 'end_year').annotate(order_count=Count('tag__taggedsheet'), order_sum=Sum("tag__taggedsheet__order")).filter(tag__taggedsheet__order__lte=max_tag_order)
        for ty in qs:
            for year in range(ty['start_year'], ty['end_year']):
                years[year] = (2*max_tag_order*ty['order_count']-ty['order_sum'])/(ty['end_year']-ty['start_year']) + years[year] if year in years else 0

    yearchange = []
    for year in sorted(years.keys()):
        score = years[year]
        if year < 2011:
            if year-1 not in years or years[year-1] != score:
                yearchange.append({'year': year, 'score': score})
            if year+1 not in years and year != -1:
                yearchange.append({'year': year+1, 'score': 0})

    output = {'count': cont_count, 'contents': contenus, 'tags':tags, 'sparkline':yearchange, 'countries':countries, 'disciplines':disciplines}
    
    return HttpResponse(content=json.dumps(output), mimetype='application/json')