Example #1
0
def buff(buff_id):
    state_dict = {'accepted': CorrelationBuff.ACCEPTED,
                  'declined': CorrelationBuff.DECLINED }
    buff = CorrelationBuff.find_one({'_id': bson.ObjectId(buff_id)})
    
    if (request.args.get('_method') == 'put'
    and state_dict.get(request.args.get('state'))):
        buff['state'] = state_dict.get(request.args.get('state'))
        CorrelationBuff.save(buff)
    
    #return json.dumps(collections.OrderedDict(
    #    'correlation': buff['correlation']
    #})
    return redirect('/buffs/')
Example #2
0
def index():
    user_tz = current_user.get('timezone', pytz.utc)
    active_buffs = {}
    active_buff_charts = []
    accepted_buffs = {}
    outstanding_buffs = []
    all_paths = ['lastfm/scrobbles/echonest/totals',
             'lastfm/scrobbles/echonest/energy/averages']
             
    # Okay, time to add in custom paths!
    for datastream, href in API.get_custom_datastreams(current_user):
        if datastream != 'self':
            all_paths.append('custom/' + datastream + '/totals')
            all_paths.append('custom/' + datastream + '/averages')
        
    group_by_intervals = {
        "day": ["year","month","day"]#, "week": ["isoyear", "isoweek"],
        #"month": ["year", "month"], "year": ["year"]
    }
    continuous = True
    
    today = datetime.datetime.now(pytz.utc).replace(
        hour = 0, minute = 0, second = 0, microsecond = 0)
    
    # Keeping track of the max_end and min_start dates of the user's accepted
    # buffs so we can determine how wide the timeline needs to be in order to
    # get the amount of spacing between ticks we want.
    max_end = None
    min_start = None
    
    # Grab any buffs the user has previously accepted.
    for buff in CorrelationBuff.find_accepted(lazy = False):
        buff = CorrelationBuff(**buff)
        chart = CorrelationBuffChart.create(current_user, buff)
        start_timestamp = int(time.mktime(
            datetime.datetime(*buff.start, tzinfo = pytz.utc).timetuple()))
        
        # If the buff does not have a non-null end date, then we will just use
        # today. Null end dates indicate active buffs.
        if buff['end']:
            end_timestamp = int(time.mktime(
                pytz.UTC.localize(buff.end).timetuple()))
        else:
            end_timestamp = int(time.mktime(
                datetime.datetime.now(pytz.utc).timetuple()))
            active_buffs[buff.key] = buff
            active_buff_charts.append(chart)
            
        if max_end == None or end_timestamp > max_end:
            max_end = end_timestamp
            
        if min_start == None or start_timestamp < min_start:
            min_start = start_timestamp
        
        # Set up the JSON data the timeline expects.
        if buff.type_key not in accepted_buffs:
            accepted_buffs[buff.type_key] = {
                "icon": "/static/images/buffs/%s" % chart['icon'],
                "times": []}
            
        # Multiplying timestamps by 1000 because the timeline expects
        # milliseconds and Python uses seconds.
        accepted_buffs[buff.type_key]["times"].append({
            "starting_time": start_timestamp * 1000,
            "ending_time": end_timestamp * 1000,
            "correlation": "%s%%" % int(round(buff["correlation"]*100)),
            "chart_data": chart["chart_data"],
            "chart_id": chart["chart_id"],
            "text": chart['text'],
            "title": chart['title']
        })
        
    # Grab any correlations the user has yet to accept or decline.
    outstanding_buffs = CorrelationBuff.find_outstanding(lazy = False)
    
    # Grab the latest buff we logged, whether it was accepted or not.
    last_buff = CorrelationBuff.find_one(None, sort = [('$end', pymongo.DESCENDING)])
    a_year_ago = (today - datetime.timedelta(days = 365))

    if last_buff:
        last_buff['end'] = pytz.UTC.localize(last_buff['end'])
        start_date = max(a_year_ago,
            last_buff['end'] + datetime.timedelta(days = 1))
    else:
        start_date = a_year_ago
    
    # If there were active buffs, we want to ask for correlations from the start
    # date of the earliest one. That way we can see if the active buffs have
    # extended out any further. This may, of course, result in some completed
    # buffs being returned *again*, so we'll have to filter those out by making
    # sure we don't include any correlations with an end date before the end
    # date of last_buff.
    correlation_start_date = today
    if active_buffs:
        for buff in active_buffs.values():
            buff_start = datetime.datetime(*buff['start'], tzinfo = pytz.utc)
            
            if buff_start < correlation_start_date:
                correlation_start_date = buff_start
    else:
        correlation_start_date = start_date
    
    # Look for new correlations.
    for interval, group_by in group_by_intervals.items():
        intervalString = ",".join(sorted(group_by))
        
        # Look for new correlations in all combinations of paths.
        for paths in itertools.combinations(all_paths, 2):
            # Just grabbing the correlations for this user from the last 30 days
            # or since the last logged buff, whichever is later.
            new_correlations = API.get_correlations(current_user, paths, group_by,
                correlation_start_date, continuous = True)
            
            # Cache all the new correlations and update active buff end times
            # where applicable.
            for correlation in new_correlations:
                end = dict(zip(correlation['group_by'], correlation['end']))
                start = dict(zip(correlation['group_by'], correlation['start']))
                end = datetime.datetime(end['year'], end['month'], end['day'],
                    tzinfo = pytz.utc)
                start = datetime.datetime(start['year'], start['month'],
                    start['day'], tzinfo = pytz.utc)
                
                # If the correlation end date is today, then we consider the buff
                # active. We want to change its end date to None.
                if today == end:
                    correlation_end = None
                else:
                    correlation_end = end
                
                del correlation['end']
                buff = CorrelationBuff.find_or_create(
                    user_id = current_user['_id'], **correlation)
                    
                if 'end' in buff and buff['end']:
                    buff['end'] = pytz.UTC.localize(buff['end'])
                                    
                # If this has an start date greater than start_date, then we know
                # we need to save it. If not, and if it doesn't correspond to an
                # active buff, then we can ignore it. The user will have already
                # been prompted with it, by definition.
                # Also, don't append outstanding buffs with IDs, since they'll
                # already be a part of the outstanding_buffs list due to our
                # earlier Pymongo query.
                if (start > start_date 
                and buff['state'] == CorrelationBuff.OUTSTANDING
                and '_id' not in buff):
                    outstanding_buffs.append(buff)
                    
                # Update the buff end date, or save the new buff if it hasn't
                # been saved before.
                if (buff['end'] != correlation_end or '_id' not in buff):
                    buff['end'] = correlation_end
                    CorrelationBuff.save(buff)
                    
                # Does this "new correlation" correspond to a previously accepted
                # active buff? Does the new correlation provide an end date for that
                # active buff? Then update the buff's end date.
                if buff.key in active_buffs and end != today:
                    active_buffs[buff.key]['end'] = correlation_end
                    CorrelationBuff.save(buff)
    
    # Format the correlations as buffs.
    outstanding_buffs = [CorrelationBuffChart.create(current_user, buff
        ) for buff in outstanding_buffs]
        
    return render_template('%s/index.html' % app.name,
        active_buff_charts = active_buff_charts,
        outstanding_buffs = outstanding_buffs, 
        accepted_buffs = json.dumps(accepted_buffs.values()
            ) if accepted_buffs else None,
        OUTSTANDING = CorrelationBuff.OUTSTANDING,
        timeline_width = ((max_end - min_start)/10000
            ) if max_end and min_start else None,
        start_year = (datetime.datetime.fromtimestamp(min_start).year
            ) if min_start else None)