Example #1
0
def approx_date_diff(start,end,mode="e",as_years=False):
    """
    A tag for transforming approximate dates into actual dates
    """
    if not end:
        end = datetime.date.today()
    elif not hasattr(end,'date'):
        print end.split('-')
        end = ApproximateDate(*map(int,end.split('-'))).date(mode)
    if not start:
        start = datetime.date.today()
    elif not hasattr(start,'date'):
        print "s", start
        print start.split('-')
        start = ApproximateDate(*map(int,start.split('-'))).date(mode)
    days = (end - start).days
    if as_years:
        days_to_years(days)
    else:
        return days
Example #2
0
def approx_date_diff(start, end, mode="e", as_years=False):
    """
    A tag for transforming approximate dates into actual dates
    """
    if not end:
        end = datetime.date.today()
    elif not hasattr(end, 'date'):
        print end.split('-')
        end = ApproximateDate(*map(int, end.split('-'))).date(mode)
    if not start:
        start = datetime.date.today()
    elif not hasattr(start, 'date'):
        print "s", start
        print start.split('-')
        start = ApproximateDate(*map(int, start.split('-'))).date(mode)
    days = (end - start).days
    if as_years:
        days_to_years(days)
    else:
        return days
Example #3
0
def events_api(request):
    aggregators = request.GET.getlist('aggregator',['chamber__title'])
    filters = request.GET.getlist('filter',[])
    since = request.GET.get('since',None)
    min_agg = request.GET.get('min',None)
    smooth = request.GET.get('smooth',False) is not False #samples only at start of service
    check_dates = request.GET.get('check_dates',False) is not False #and smooth # only do extra date checking if smooth otherwise this will thrash the DB
    show_totals = request.GET.get('totals',False) is not False
    fils = {}
    for f in filters:
        fil,val = f.split('|')
        fils[fil]=val
    event_type = models.Service.objects
    if since:
        since = ApproximateDate(*map(int,since.split('-'))).early()
    #events = event_type.filter(Q(end_date__gt=since)|Q(end_date='')).filter(**fils) # Pre-filter the events to look at
    events = event_type.filter(**fils) # Pre-filter the events to look at
    
    from datetime import timedelta, date

    available_keys = []
    candidate_keys = events.values(*aggregators).order_by().distinct()
    if min_agg:
        candidate_keys = candidate_keys.annotate(count=Count('person'))

    totals = {}
    ds = key_dates = {}
    for k in candidate_keys:
        if min_agg:
            l = [k[agg] for agg in aggregators if k[agg] is not None and k['count'] > int(min_agg)]
        else:
            l = [k[agg] for agg in aggregators if k[agg] is not None]
        if l:
            k = '-'.join(l)
            ds[k]={'keys':l,'data':{}} # set up whole date structure here
            available_keys.append(k)

    def get_date_data_for_query(query,query_date):
        # We call this in two places and only within this function, and it needs to modify a ton of local stuff
        # So a local function with 2 arguments is a better pattern than a module function with the 7 or so arguments.
        
        membership_aggs = [a for a in aggregators if "membership" in a]
        if check_dates and membership_aggs:
            for a in membership_aggs:
                f=a.split("membership",1)[0]+'membership' # Get just the membership part
                query &= Q(**{f+'__start_date__lte':query_date}) 
                query &= (Q(**{f+'__end_date__gte':query_date}) | Q(**{f+'__end_date__isnull':True}))

        val = events.filter(query).values(*aggregators).order_by().distinct().annotate(*[Count(a) for a in aggregators])
        #print val
        for k in ds.keys():
            ds[k]['data'][str(query_date)] = 0
        for v in val:
            agg_var = "-".join([str(v[x]) for x in aggregators])
            if agg_var in ds.keys():
                ds[agg_var]['data'][str(query_date)] = int(v[aggregators[0]+'__count'])

        if show_totals:
            total = events.filter(query).count()
            totals[str(query_date)] = total

    for e in events.order_by("start_date"):
        dates = [e.start_date,e.end_date]
        if smooth:
            dates = [e.start_date]
        for event_date in dates:
            if event_date:
                day_after = event_date + timedelta(days=1)
                days = [day_after]
                if not smooth:
                    day_before = event_date - timedelta(days=1)
                    days = [day_before,day_after]
                for query_date in days:
                    if not since or query_date > since:
                        query = Q(start_date__lte=query_date) & (Q(end_date__gt= query_date) | Q(end_date__isnull=True))
                        #get_date_data_for_query(key_dates,events,query,query_date,aggregators,available_keys)
                        get_date_data_for_query(query,query_date)

    today = date.today()
    if today not in key_dates.keys():
        query = Q(end_date__isnull=True)
        #get_date_data_for_query(key_dates,events,query,today,aggregators,available_keys)
        get_date_data_for_query(query,today)
    
    # sort the dates properly
    keys = []
    for agg,struct in key_dates.items():
        d = struct['data']
        struct['data'] = OrderedDict(sorted(d.items(), key=lambda t: t[0]))
    
    output = {'metadata':[],'data':key_dates}
    if show_totals:
        output['totals'] = totals
    return output