def update_timeline(session):
    logging.info('Updating %s' % session.twitter_id)

    stream = data.StreamData.get_or_create_timeline_for_user(session.twitter_id)

    # For the sake of efficiency, only get tweets since the most recently
    # received one. However, Twitter has had out-of-order delivery issues in the
    # past, so if the most recent status is recent (~10 minutes), pick the
    # oldest one that falls outside that window.
    since_id = None
    if stream.status_ids:
        threshold_time = time.time() - RECENT_STATUS_INTERVAL_SEC
        for i in xrange(0, len(stream.status_ids)):
          since_id = stream.status_ids[i]
          if stream.status_timestamps_sec[i] < threshold_time:
              break

    api = session.create_api()
    # TODO(mihaip): Support paging back if more than 200 statuses were received
    # since the last update.
    timeline = api.GetHomeTimeline(count=200, since_id=since_id)
    logging.info('Got back %d statuses' % len(timeline))

    known_status_ids = set(stream.status_ids)
    new_status_ids = []
    new_status_timestamps_sec = []
    new_statueses_by_id = {}

    for status in timeline:
        if status.id in known_status_ids:
            continue
        new_status_ids.append(status.id)
        new_status_timestamps_sec.append(status.created_at_in_seconds)
        new_statueses_by_id[status.id] = status

    if not new_status_ids:
        logging.info('  No new status IDs')
        return False, stream.status_ids

    logging.info('  %d new status IDs for this stream' % len(new_status_ids))

    dropped_status_ids = 0
    combined_status_ids = list(new_status_ids)
    combined_status_timestamps_sec = list(new_status_timestamps_sec)
    threshold_time = time.time() - OLD_STATUS_INTERVAL_SEC
    for status_id, timestamp_sec in itertools.izip(stream.status_ids, stream.status_timestamps_sec):
        if timestamp_sec >= threshold_time:
            combined_status_ids.append(status_id)
            combined_status_timestamps_sec.append(timestamp_sec)
        else:
            dropped_status_ids += 1

    logging.info('  Dropped %d old status IDs' % dropped_status_ids)

    stream.status_ids = combined_status_ids
    stream.status_timestamps_sec = combined_status_timestamps_sec

    unknown_status_ids = data.StatusData.get_unknown_status_ids(new_status_ids)

    if not unknown_status_ids:
        logging.info('  No new statuses')
        stream.put()
        # Even though there were no new statuses to store, the timeline still
        # had new tweets, so we want the hub to be pinged.
        return True, stream.status_ids
    logging.info('  %d new statuses' % len(unknown_status_ids))

    unknown_statuses = [
        data.StatusData.from_status(new_statueses_by_id[id])
        for id in unknown_status_ids
    ]
    db.put(unknown_statuses)

    # We only put the stream data now, so that if the status put above failed,
    # we will still attempt to recreate the items on the next fetch.
    stream.put()

    return True, stream.status_ids
dataset/ETHPy150Open mihaip/streamspigot/app/birdfeeder/handlers/update.py/update_timeline/original