示例#1
0
def template_context_processor(request):
    # These are good to have in a context processor and not middleware
    # because they won't be evaluated until template evaluation, which
    # might have user-info blocked already for caching (a good thing).
    
    context = dict(base_context) # clone
    
    # Add top-tracked feeds.
    from events.models import Feed
    global trending_feeds
    if settings.DEBUG and False:
        trending_feeds = [None, []]
    elif not trending_feeds or trending_feeds[0] < datetime.datetime.now()-datetime.timedelta(hours=2):
        trf = cache.get("trending_feeds")
        if not trf:
            trf = Feed.get_trending_feeds()
            cache.set("trending_feeds", trf, 60*60*2)
        trending_feeds = (datetime.datetime.now(), [Feed.objects.get(id=f) for f in trf])
    context["trending_feeds"] = trending_feeds[1]
    context["trending_bill_feeds"] = [f for f in trending_feeds[1] if f.feedname.startswith("bill:")]

    # Add site-wide tracked events.
    all_tracked_events = cache.get("all_tracked_events")
    if not all_tracked_events:
        all_tracked_events = Feed.get_events_for([fn for fn in ("misc:activebills2", "misc:billsummaries", "misc:allvotes") if Feed.objects.filter(feedname=fn).exists()], 6)
        cache.set("all_tracked_events", all_tracked_events, 60*15) # 15 minutes
    context["all_tracked_events"] = all_tracked_events

    # Get our latest Medium posts.
    medium_posts = cache.get("medium_posts")
    if not medium_posts:
        from website.models import MediumPost
        medium_posts = MediumPost.objects.order_by('-published')[0:6]
        cache.set("medium_posts", medium_posts, 60*15) # 15 minutes
    context["medium_posts"] = medium_posts

    # Add context variables for whether the user is in the
    # House or Senate netblocks.
    
    try:
        ip = request.META["REMOTE_ADDR"]
        ip = ip.replace("::ffff:", "") # ipv6 wrapping ipv4
        
        if is_ip_in_any_range(ip, HOUSE_NET_RANGES):
            context["remote_net_house"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, SENATE_NET_RANGES):
            context["remote_net_senate"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, EOP_NET_RANGES):
            context["remote_net_eop"] = True
            request._track_this_user = True
    except:
        pass
    
    return context
示例#2
0
    def build_info():
        # feeds about all legislation that we offer the user to subscribe to
        feeds = [f for f in Feed.get_simple_feeds() if f.category == "federal-bills"]

        # info about bills by status
        groups = [
            (   g[0], # title
                g[1], # text 1
                g[2], # text 2
                "/congress/bills/browse?status=" + ",".join(str(s) for s in g[4]) + "&sort=-current_status_date", # link
               load_bill_status_qs(g[4]).count(), # count in category
               load_bill_status_qs(g[4]).order_by('-current_status_date')[0:6], # top 6 in this category
                )
            for g in bill_status_groups ]

        # legislation coming up
        dhg_bills = Bill.objects.filter(congress=CURRENT_CONGRESS, docs_house_gov_postdate__gt=datetime.datetime.now() - datetime.timedelta(days=10)).filter(docs_house_gov_postdate__gt=F('current_status_date'))
        sfs_bills = Bill.objects.filter(congress=CURRENT_CONGRESS, senate_floor_schedule_postdate__gt=datetime.datetime.now() - datetime.timedelta(days=5)).filter(senate_floor_schedule_postdate__gt=F('current_status_date'))
        coming_up = list((dhg_bills | sfs_bills).order_by('scheduled_consideration_date'))

        # top tracked bills
        top_bills = Feed.objects\
            .filter(feedname__startswith='bill:')\
            .filter(feedname__regex='^bill:[hs][jcr]?%d-' % CURRENT_CONGRESS)
        top_bills = top_bills\
            .annotate(count=Count('tracked_in_lists'))\
            .order_by('-count')\
            .values('feedname', 'count')\
            [0:25]
        top_bills = [(Bill.from_feed(Feed.from_name(bf["feedname"])), bf["count"]) for bf in top_bills]

        # trending bills
        trf = Feed.get_trending_feeds()
        trf = [Feed.objects.get(id=f) for f in trf]
        trending_bill_feeds = [f for f in trf if f.feedname.startswith("bill:")]

        return {
            "feeds": feeds,

            "total": Bill.objects.filter(congress=CURRENT_CONGRESS).count(),
            "current_congress": CURRENT_CONGRESS,
            "current_congress_dates": get_congress_dates(CURRENT_CONGRESS),

            "groups": groups,
            "coming_up": coming_up,
            "top_tracked_bills": top_bills,
            "trending_bill_feeds": trending_bill_feeds,

            "subjects": subject_choices(),
            "BILL_STATUS_INTRO": (BillStatus.introduced, BillStatus.reported),
        }
示例#3
0
    def build_info():
        # feeds about all legislation that we offer the user to subscribe to
        feeds = [f for f in Feed.get_simple_feeds() if f.category == "federal-bills"]

        # info about bills by status
        groups = [
            (   g[0], # title
                g[1], # text 1
                g[2], # text 2
                "/congress/bills/browse?status=" + ",".join(str(s) for s in g[4]) + "&sort=-current_status_date", # link
               load_bill_status_qs(g[4]).count(), # count in category
               load_bill_status_qs(g[4]).order_by('-current_status_date')[0:6], # top 6 in this category
                )
            for g in bill_status_groups ]

        # legislation coming up
        dhg_bills = Bill.objects.filter(congress=CURRENT_CONGRESS, docs_house_gov_postdate__gt=datetime.datetime.now() - datetime.timedelta(days=10)).filter(docs_house_gov_postdate__gt=F('current_status_date'))
        sfs_bills = Bill.objects.filter(congress=CURRENT_CONGRESS, senate_floor_schedule_postdate__gt=datetime.datetime.now() - datetime.timedelta(days=5)).filter(senate_floor_schedule_postdate__gt=F('current_status_date'))
        coming_up = list((dhg_bills | sfs_bills).order_by('scheduled_consideration_date'))

        # top tracked bills
        top_bills = Feed.objects\
            .filter(feedname__startswith='bill:')\
            .filter(feedname__regex='^bill:[hs][jcr]?%d-' % CURRENT_CONGRESS)
        top_bills = top_bills\
            .annotate(count=Count('tracked_in_lists'))\
            .order_by('-count')\
            .values('feedname', 'count')\
            [0:25]
        top_bills = [(Bill.from_feed(Feed.from_name(bf["feedname"])), bf["count"]) for bf in top_bills]

        # trending bills
        trf = Feed.get_trending_feeds()
        trf = [Feed.objects.get(id=f) for f in trf]
        trending_bill_feeds = [f for f in trf if f.feedname.startswith("bill:")]

        return {
            "feeds": feeds,

            "total": Bill.objects.filter(congress=CURRENT_CONGRESS).count(),
            "current_congress": CURRENT_CONGRESS,
            "current_congress_dates": get_congress_dates(CURRENT_CONGRESS),

            "groups": groups,
            "coming_up": coming_up,
            "top_tracked_bills": top_bills,
            "trending_bill_feeds": trending_bill_feeds,

            "subjects": subject_choices(),
            "BILL_STATUS_INTRO": (BillStatus.introduced, BillStatus.reported),
        }
示例#4
0
def template_context_processor(request):
    # These are good to have in a context processor and not middleware
    # because they won't be evaluated until template evaluation, which
    # might have user-info blocked already for caching (a good thing).
    
    context = dict(base_context) # clone
    
    #if hasattr(request, 'user') and request.user.is_authenticated() and BouncedEmail.objects.filter(user=request.user).exists(): context["user_has_bounced_mail"] = True
    
    # Add top-tracked feeds.
    from events.models import Feed
    global trending_feeds
    if settings.DEBUG and False:
        trending_feeds = [None, []]
    elif not trending_feeds or trending_feeds[0] < datetime.datetime.now()-datetime.timedelta(hours=2):
        trf = cache.get("trending_feeds")
        if not trf:
            trf = Feed.get_trending_feeds()
            cache.set("trending_feeds", trf, 60*60*2)
        trending_feeds = (datetime.datetime.now(), [Feed.objects.get(id=f) for f in trf])
    context["trending_feeds"] = trending_feeds[1]
    context["trending_bill_feeds"] = [f for f in trending_feeds[1] if f.feedname.startswith("bill:")]

    # Add site-wide tracked events.
    all_tracked_events = cache.get("all_tracked_events")
    if not all_tracked_events:
        all_tracked_events = Feed.get_events_for([fn for fn in ("misc:activebills2", "misc:billsummaries", "misc:allvotes") if Feed.objects.filter(feedname=fn).exists()], 6)
        cache.set("all_tracked_events", all_tracked_events, 60*15) # 15 minutes
    context["all_tracked_events"] = all_tracked_events

    # Get our latest Medium posts.
    medium_posts = cache.get("medium_posts")
    if not medium_posts:
        from website.models import MediumPost
        medium_posts = MediumPost.objects.order_by('-published')[0:6]
        cache.set("medium_posts", medium_posts, 60*15) # 15 minutes
    context["medium_posts"] = medium_posts

    # Get a campaign from if.then.fund.
    itf_active_campaign = 50
    if_then_fund_campaign = cache.get("if_then_fund_campaign")
    if not if_then_fund_campaign and itf_active_campaign:
        try:
            if_then_fund_campaign = json.load(urllib2.urlopen("https://if.then.fund/a/%d.json" % itf_active_campaign))
        except:
            if_then_fund_campaign = "UHM" # something that is truthy otherwise we'll ping on every request
    	cache.set("if_then_fund_campaign", if_then_fund_campaign, 60*45) # 45 minutes
    context["if_then_fund_campaign"] = if_then_fund_campaign

    # Add context variables for whether the user is in the
    # House or Senate netblocks.
    
    def ip_to_quad(ip):
        return [int(s) for s in ip.split(".")]
    def compare_ips(ip1, ip2):
        return cmp(ip_to_quad(ip1), ip_to_quad(ip2))
    def is_ip_in_range(ip, block):
       return compare_ips(ip, block[0]) >= 0 and compare_ips(ip, block[1]) <= 0
    def is_ip_in_any_range(ip, blocks):
       for block in blocks:
           if is_ip_in_range(ip, block):
               return True
       return False
    
    try:
        ip = request.META["REMOTE_ADDR"]
        ip = ip.replace("::ffff:", "") # ipv6 wrapping ipv4
        
        if is_ip_in_any_range(ip, HOUSE_NET_RANGES):
            context["remote_net_house"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, SENATE_NET_RANGES):
            context["remote_net_senate"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, EOP_NET_RANGES):
            context["remote_net_eop"] = True
            request._track_this_user = True
    except:
        pass
    
    # Add a context variable for if the user is near DC geographically.

    user_loc = None
    try:
        if settings.GEOIP_DB_PATH and not request.path.startswith("/api/") and False:
            user_loc = geo_ip_db.geos(ip)
            context["is_dc_local"] = user_loc.distance(washington_dc) < .5
    except:
        pass

    if not hasattr(request, 'user') or not request.user.is_authenticated():
        # Have we put the user's district in a cookie?
        try:
            cong_dist = json.loads(request.COOKIES["cong_dist"])
            x = cong_dist["state"] # validate fields are present
            x = int(cong_dist["district"]) # ...and valid
        except:
            cong_dist = None

        # Geolocate to a congressional district if not known and save it in
        # a cookie for next time.
        if user_loc and not cong_dist and not request.path.startswith("/api/"):
            try:
                from person.views import do_district_lookup
                cong_dist = do_district_lookup(*user_loc.coords)
                x = cong_dist["state"] # validate fields are present
                x = int(cong_dist["district"]) # ...and valid
                request._save_cong_dist = cong_dist
            except:
                cong_dist = None

    else:
        # If the user is logged in, is the district in the user's profile?
        profile = request.user.userprofile()
        if profile.congressionaldistrict != None:
            # pass through XX00 so site knows not to prompt
            cong_dist = { "state": profile.congressionaldistrict[0:2], "district": int(profile.congressionaldistrict[2:]) }
        else:
            cong_dist = None

    # If we have a district, get its MoCs.
    if cong_dist:
        from person.models import Person
        context["congressional_district"] = json.dumps(cong_dist)
        context["congressional_district_mocs"] = json.dumps([p.id for p in Person.from_state_and_district(cong_dist["state"], cong_dist["district"])])

    return context
示例#5
0
def index(request):
    # Fetch subject areas for drop-down.
    from bill.views import subject_choices
    bill_subject_areas = subject_choices()

    post_groups = []

    # Fetch our Medium posts for summaries and features.
    from website.models import MediumPost
    post_groups.append({
        "title":
        "What We're Watching",
        "posts":
        MediumPost.objects.order_by('-published')[0:3],
        "link":
        "/events/govtrack-insider",
        "link_text":
        "Subscribe to all GovTrack Insider articles",
    })

    # legislation coming up
    from django.db.models import F
    from django.conf import settings
    from bill.models import Bill
    dhg_bills = Bill.objects.filter(
        congress=settings.CURRENT_CONGRESS,
        docs_house_gov_postdate__gt=datetime.now() -
        timedelta(days=10)).filter(
            docs_house_gov_postdate__gt=F('current_status_date'))
    sfs_bills = Bill.objects.filter(
        congress=settings.CURRENT_CONGRESS,
        senate_floor_schedule_postdate__gt=datetime.now() -
        timedelta(days=5)).filter(
            senate_floor_schedule_postdate__gt=F('current_status_date'))
    coming_up = list((dhg_bills | sfs_bills))
    coming_up.sort(key=lambda bill: -bill.proscore())
    if len(coming_up) > 0:
        post_groups.append({
            "title":
            "Legislation Coming Up",
            "posts": [{
                "image_url":
                bill.get_thumbnail_url_ex(),
                "title":
                bill.title,
                "url":
                bill.get_absolute_url(),
                "published":
                "week of " + bill.scheduled_consideration_date.strftime("%x"),
            } for bill in coming_up[0:3]],
            "link":
            "/congress/bills",
            "link_text":
            "View All",
        })

    # recent oversight topics
    from oversight.models import OversightTopic
    oversight_topics = OversightTopic.objects.filter(
        congress_end__gte=settings.CURRENT_CONGRESS).order_by('-updated')[0:3]
    if oversight_topics:
        post_groups.append({
            "title":
            "Congressional Oversight and Investigations",
            "posts": [{
                "title": topic.title,
                "url": topic.get_absolute_url(),
                "published": topic.post_date,
            } for topic in oversight_topics],
            "link":
            "/congress/oversight",
            "link_text":
            "View All",
        })

    # trending feeds
    trending_feeds = [
        Feed.objects.get(id=f) for f in Feed.get_trending_feeds()[0:6]
    ]
    if len(trending_feeds) > 0:
        post_groups.append({
            "title":
            "Trending",
            "posts": [{
                "title": feed.title,
                "url": feed.link,
            } for feed in trending_feeds]
        })

    from person.models import Person
    from vote.models import Vote
    return {
        # for the action area below the splash
        'bill_subject_areas': bill_subject_areas,

        # for the highlights blocks
        'post_groups': post_groups,
    }
示例#6
0
def template_context_processor(request):
    # These are good to have in a context processor and not middleware
    # because they won't be evaluated until template evaluation, which
    # might have user-info blocked already for caching (a good thing).
    
    context = {
        "SITE_ROOT_URL": settings.SITE_ROOT_URL,
        "GOOGLE_ANALYTICS_KEY": settings.GOOGLE_ANALYTICS_KEY
    }
    
    if request.user.is_authenticated() and BouncedEmail.objects.filter(user=request.user).exists(): context["user_has_bounced_mail"] = True
    
    # Add top-tracked feeds.
    global trending_feeds
    if not trending_feeds or trending_feeds[0] < datetime.datetime.now()-datetime.timedelta(hours=2):
        from events.models import Feed
        trf = cache.get("trending_feeds")
        if not trf:
            trf = Feed.get_trending_feeds()
            cache.set("trending_feeds", trf, 60*60*2)
        trending_feeds = (datetime.datetime.now(), [Feed.objects.get(id=f) for f in trf])
    context["trending_feeds"] = trending_feeds[1]
    
    # Add context variables for whether the user is in the
    # House or Senate netblocks.
    
    def ip_to_quad(ip):
        return [int(s) for s in ip.split(".")]
    def compare_ips(ip1, ip2):
        return cmp(ip_to_quad(ip1), ip_to_quad(ip2))
    def is_ip_in_range(ip, block):
       return compare_ips(ip, block[0]) >= 0 and compare_ips(ip, block[1]) <= 0
    def is_ip_in_any_range(ip, blocks):
       for block in blocks:
           if is_ip_in_range(ip, block):
               return True
       return False
    
    try:
        ip = request.META["REMOTE_ADDR"]
        ip = ip.replace("::ffff:", "") # ipv6 wrapping ipv4
        
        if is_ip_in_any_range(ip, HOUSE_NET_RANGES):
            context["remote_net_house"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, SENATE_NET_RANGES):
            context["remote_net_senate"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, EOP_NET_RANGES):
            context["remote_net_eop"] = True
            request._track_this_user = True
        
        try:
            cong_dist = json.loads(request.COOKIES["cong_dist"])
        except:
            cong_dist = None
        
        if settings.GEOIP_DB_PATH:
            user_loc = geo_ip_db.geos(ip)
            context["is_dc_local"] = user_loc.distance(washington_dc) < .5
            
            # geolocate to a congressional district if not known
            if not cong_dist and False:
                from person.views import do_district_lookup
                cong_dist = do_district_lookup(*user_loc.coords)
                cong_dist["queried"] = True

        if cong_dist and "error" not in cong_dist:
            from person.models import PersonRole, RoleType, Gender
            import random
            def get_key_vote(p):
                from vote.models import Vote
                
                v = 113340
                descr = "CISPA"
                
                v = Vote.objects.get(id=v)
                try:
                    return {
                        "link": v.get_absolute_url(),
                        "description": descr,
                        "option": p.votes.get(vote=v).option.key,
                    }
                except:
                    return None
            def fmt_role(r):
                return {
                    "id": r.person.id,
                    "name": r.person.name_and_title(),
                    "link": r.person.get_absolute_url(),
                    "type": RoleType.by_value(r.role_type).key,
                    "pronoun": Gender.by_value(r.person.gender).pronoun,
                    "key_vote": get_key_vote(r.person),
                }
            qs = PersonRole.objects.filter(current=True).select_related("person")    
            cong_dist["reps"] = [fmt_role(r) for r in 
                qs.filter(role_type=RoleType.representative, state=cong_dist["state"], district=cong_dist["district"])
                | qs.filter(role_type=RoleType.senator, state=cong_dist["state"])]
                
            if settings.DEBUG:
                # I need to test with more than my rep (just our DC delegate).
                cong_dist["reps"] = [fmt_role(r) for r in random.sample(PersonRole.objects.filter(current=True), 3)]
            
            random.shuffle(cong_dist["reps"]) # for varied output
            
            context["geolocation"] = json.dumps(cong_dist)
        if cong_dist: # whether or not error
            request.cong_dist_info = cong_dist
                
    except:
        pass
    
    return context
示例#7
0
def template_context_processor(request):
    # These are good to have in a context processor and not middleware
    # because they won't be evaluated until template evaluation, which
    # might have user-info blocked already for caching (a good thing).
    
    context = {
        "SITE_ROOT_URL": settings.SITE_ROOT_URL,
        "GOOGLE_ANALYTICS_KEY": settings.GOOGLE_ANALYTICS_KEY,
        "STATE_CHOICES": sorted([(kv[0], kv[1], us.stateapportionment[kv[0]]) for kv in us.statenames.items() if kv[0] in us.stateapportionment], key = lambda kv : kv[1]),
    }
    
    if hasattr(request, 'user') and request.user.is_authenticated() and BouncedEmail.objects.filter(user=request.user).exists(): context["user_has_bounced_mail"] = True
    
    # Add top-tracked feeds.
    global trending_feeds
    if settings.DEBUG:
        trending_feeds = [None, []]
    elif not trending_feeds or trending_feeds[0] < datetime.datetime.now()-datetime.timedelta(hours=2):
        from events.models import Feed
        trf = cache.get("trending_feeds")
        if not trf:
            trf = Feed.get_trending_feeds()
            cache.set("trending_feeds", trf, 60*60*2)
        trending_feeds = (datetime.datetime.now(), [Feed.objects.get(id=f) for f in trf])
    context["trending_feeds"] = trending_feeds[1]

    # Highlight a recent vote. We don't yet need to know the user's district
    # --- that will happen client-side.
    def get_highlighted_vote():
        from vote.models import Vote, VoteCategory
        candidate_votes = Vote.objects.filter(category__in=Vote.MAJOR_CATEGORIES).exclude(related_bill=None).order_by('-created')
        for v in candidate_votes:
            return { "title": v.question, "link": v.get_absolute_url(), "data": v.simple_record() }
        return "NONE"
    highlighted_vote = cache.get("highlighted_vote")
    if highlighted_vote is None:
        highlighted_vote = get_highlighted_vote()
        cache.set("highlighted_vote", highlighted_vote, 60*60*2)
    if highlighted_vote != "NONE":
        context["highlighted_vote"] = highlighted_vote
    
    # Add context variables for whether the user is in the
    # House or Senate netblocks.
    
    def ip_to_quad(ip):
        return [int(s) for s in ip.split(".")]
    def compare_ips(ip1, ip2):
        return cmp(ip_to_quad(ip1), ip_to_quad(ip2))
    def is_ip_in_range(ip, block):
       return compare_ips(ip, block[0]) >= 0 and compare_ips(ip, block[1]) <= 0
    def is_ip_in_any_range(ip, blocks):
       for block in blocks:
           if is_ip_in_range(ip, block):
               return True
       return False
    
    try:
        ip = request.META["REMOTE_ADDR"]
        ip = ip.replace("::ffff:", "") # ipv6 wrapping ipv4
        
        if is_ip_in_any_range(ip, HOUSE_NET_RANGES):
            context["remote_net_house"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, SENATE_NET_RANGES):
            context["remote_net_senate"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, EOP_NET_RANGES):
            context["remote_net_eop"] = True
            request._track_this_user = True
    except:
        pass
    
    # Add a context variable for if the user is near DC geographically.

    user_loc = None
    try:
        if settings.GEOIP_DB_PATH and not request.path.startswith("/api/"):
            user_loc = geo_ip_db.geos(ip)
            context["is_dc_local"] = user_loc.distance(washington_dc) < .5
    except:
        pass

    if not hasattr(request, 'user') or not request.user.is_authenticated():
        # Have we put the user's district in a cookie?
        try:
            cong_dist = json.loads(request.COOKIES["cong_dist"])
            x = cong_dist["state"] # validate fields are present
            x = int(cong_dist["district"]) # ...and valid
        except:
            cong_dist = None

        # Geolocate to a congressional district if not known and save it in
        # a cookie for next time.
        if user_loc and not cong_dist and not request.path.startswith("/api/"):
            try:
                from person.views import do_district_lookup
                cong_dist = do_district_lookup(*user_loc.coords)
                x = cong_dist["state"] # validate fields are present
                x = int(cong_dist["district"]) # ...and valid
                request._save_cong_dist = cong_dist
            except:
                cong_dist = None

    else:
        # If the user is logged in, is the district in the user's profile?
        profile = request.user.userprofile()
        if profile.congressionaldistrict != None:
            # pass through XX00 so site knows not to prompt
            cong_dist = { "state": profile.congressionaldistrict[0:2], "district": int(profile.congressionaldistrict[2:]) }
        else:
            cong_dist = None

    # If we have a district, get its MoCs.
    if cong_dist:
        from person.models import Person
        context["congressional_district"] = json.dumps(cong_dist)
        context["congressional_district_mocs"] = json.dumps([p.id for p in Person.from_state_and_district(cong_dist["state"], cong_dist["district"])])

    return context
def template_context_processor(request):
    # These are good to have in a context processor and not middleware
    # because they won't be evaluated until template evaluation, which
    # might have user-info blocked already for caching (a good thing).

    context = dict(base_context)  # clone

    #if hasattr(request, 'user') and request.user.is_authenticated() and BouncedEmail.objects.filter(user=request.user).exists(): context["user_has_bounced_mail"] = True

    # Add top-tracked feeds.
    from events.models import Feed
    global trending_feeds
    if settings.DEBUG and False:
        trending_feeds = [None, []]
    elif not trending_feeds or trending_feeds[0] < datetime.datetime.now(
    ) - datetime.timedelta(hours=2):
        trf = cache.get("trending_feeds")
        if not trf:
            trf = Feed.get_trending_feeds()
            cache.set("trending_feeds", trf, 60 * 60 * 2)
        trending_feeds = (datetime.datetime.now(),
                          [Feed.objects.get(id=f) for f in trf])
    context["trending_feeds"] = trending_feeds[1]
    context["trending_bill_feeds"] = [
        f for f in trending_feeds[1] if f.feedname.startswith("bill:")
    ]

    # Add site-wide tracked events.
    all_tracked_events = cache.get("all_tracked_events")
    if not all_tracked_events:
        all_tracked_events = Feed.get_events_for([
            fn for fn in ("misc:activebills2", "misc:billsummaries",
                          "misc:allvotes")
            if Feed.objects.filter(feedname=fn).exists()
        ], 6)
        cache.set("all_tracked_events", all_tracked_events,
                  60 * 15)  # 15 minutes
    context["all_tracked_events"] = all_tracked_events

    # Get our latest Medium posts.
    medium_posts = cache.get("medium_posts")
    if not medium_posts:
        from website.models import MediumPost
        medium_posts = MediumPost.objects.order_by('-published')[0:6]
        cache.set("medium_posts", medium_posts, 60 * 15)  # 15 minutes
    context["medium_posts"] = medium_posts

    # Get a campaign from if.then.fund.
    itf_active_campaign = 0
    if_then_fund_campaign = cache.get("if_then_fund_campaign_%d" %
                                      itf_active_campaign)
    if not if_then_fund_campaign and itf_active_campaign:
        try:
            if_then_fund_campaign = json.load(
                urllib2.urlopen("https://if.then.fund/a/%d.json" %
                                itf_active_campaign))
        except:
            if_then_fund_campaign = "UHM"  # something that is truthy otherwise we'll ping on every request
        cache.set("if_then_fund_campaign_%d" % itf_active_campaign,
                  if_then_fund_campaign, 60 * 45)  # 45 minutes
    context["if_then_fund_campaign"] = if_then_fund_campaign

    # Add context variables for whether the user is in the
    # House or Senate netblocks.

    def ip_to_quad(ip):
        return [int(s) for s in ip.split(".")]

    def compare_ips(ip1, ip2):
        return cmp(ip_to_quad(ip1), ip_to_quad(ip2))

    def is_ip_in_range(ip, block):
        return compare_ips(ip, block[0]) >= 0 and compare_ips(ip,
                                                              block[1]) <= 0

    def is_ip_in_any_range(ip, blocks):
        for block in blocks:
            if is_ip_in_range(ip, block):
                return True
        return False

    try:
        ip = request.META["REMOTE_ADDR"]
        ip = ip.replace("::ffff:", "")  # ipv6 wrapping ipv4

        if is_ip_in_any_range(ip, HOUSE_NET_RANGES):
            context["remote_net_house"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, SENATE_NET_RANGES):
            context["remote_net_senate"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, EOP_NET_RANGES):
            context["remote_net_eop"] = True
            request._track_this_user = True
    except:
        pass

    # Add a context variable for if the user is near DC geographically.

    user_loc = None
    try:
        if settings.GEOIP_DB_PATH and not request.path.startswith(
                "/api/") and False:
            user_loc = geo_ip_db.geos(ip)
            context["is_dc_local"] = user_loc.distance(washington_dc) < .5
    except:
        pass

    if not hasattr(request, 'user') or not request.user.is_authenticated():
        # Have we put the user's district in a cookie?
        try:
            cong_dist = json.loads(request.COOKIES["cong_dist"])
            x = cong_dist["state"]  # validate fields are present
            x = int(cong_dist["district"])  # ...and valid
        except:
            cong_dist = None

        # Geolocate to a congressional district if not known and save it in
        # a cookie for next time.
        if user_loc and not cong_dist and not request.path.startswith("/api/"):
            try:
                from person.views import do_district_lookup
                cong_dist = do_district_lookup(*user_loc.coords)
                x = cong_dist["state"]  # validate fields are present
                x = int(cong_dist["district"])  # ...and valid
                request._save_cong_dist = cong_dist
            except:
                cong_dist = None

    else:
        # If the user is logged in, is the district in the user's profile?
        profile = request.user.userprofile()
        if profile.congressionaldistrict != None:
            # pass through XX00 so site knows not to prompt
            cong_dist = {
                "state": profile.congressionaldistrict[0:2],
                "district": int(profile.congressionaldistrict[2:])
            }
        else:
            cong_dist = None

    # If we have a district, get its MoCs.
    if cong_dist:
        from person.models import Person
        context["congressional_district"] = json.dumps(cong_dist)
        context["congressional_district_mocs"] = json.dumps([
            p.id for p in Person.from_state_and_district(
                cong_dist["state"], cong_dist["district"])
        ])

    return context
示例#9
0
def index(request):
    # Fetch subject areas for drop-down.
    from bill.views import subject_choices
    bill_subject_areas = subject_choices()

    post_groups = []

    # Fetch our Medium posts for summaries and features.
    from website.models import MediumPost
    post_groups.append({
        "title": "What We're Watching",
        "posts": MediumPost.objects.order_by('-published')[0:3],
        "link": "/events/govtrack-insider",
        "link_text": "Subscribe to all GovTrack Insider articles",
    })

    # legislation coming up
    from django.db.models import F
    from django.conf import settings
    from bill.models import Bill
    dhg_bills = Bill.objects.filter(congress=settings.CURRENT_CONGRESS, docs_house_gov_postdate__gt=datetime.now() - timedelta(days=10)).filter(docs_house_gov_postdate__gt=F('current_status_date'))
    sfs_bills = Bill.objects.filter(congress=settings.CURRENT_CONGRESS, senate_floor_schedule_postdate__gt=datetime.now() - timedelta(days=5)).filter(senate_floor_schedule_postdate__gt=F('current_status_date'))
    coming_up = list((dhg_bills | sfs_bills))
    coming_up.sort(key = lambda bill : -bill.proscore())
    if len(coming_up) > 0:
        post_groups.append({
            "title": "Legislation Coming Up",
            "posts": [{
                "image_url": bill.get_thumbnail_url_ex(),
                "title": bill.title,
                "url": bill.get_absolute_url(),
                "published": "week of " + bill.scheduled_consideration_date.strftime("%x"),
            } for bill in coming_up[0:3]],
            "link": "/congress/bills",
            "link_text": "View All",
        })

    # recent oversight topics
    from oversight.models import OversightTopic
    oversight_topics = OversightTopic.objects.filter(congress_end__gte=settings.CURRENT_CONGRESS).order_by('-updated')[0:3]
    if oversight_topics:
        post_groups.append({
            "title": "Congressional Oversight and Investigations",
            "posts": [{
                "title": topic.title,
                "url": topic.get_absolute_url(),
                "published": topic.post_date,
            } for topic in oversight_topics],
            "link": "/congress/oversight",
            "link_text": "View All",
        })

    # trending feeds
    trending_feeds = [Feed.objects.get(id=f) for f in Feed.get_trending_feeds()[0:6]]
    if len(trending_feeds) > 0:
        post_groups.append({
            "title": "Trending",
            "posts": [{
                "title": feed.title,
                "url": feed.link,
            } for feed in trending_feeds
        ]})


    from person.models import Person
    from vote.models import Vote
    return {
        # for the splash
        'number_of_bills': Bill.objects.filter(congress=settings.CURRENT_CONGRESS).count(),
        'number_of_legislators': Person.objects.filter(roles__current=True).count(),
        'number_of_votes': Vote.objects.filter(created__year=datetime.now().year).count(),

        # for the action area below the splash
        'bill_subject_areas': bill_subject_areas,

        # for the highlights blocks
        'post_groups': post_groups,
        }
示例#10
0
def index(request):
    # Fetch subject areas for drop-down.
    from bill.views import subject_choices
    bill_subject_areas = subject_choices()

    post_groups = []

    # Fetch our latest YouTube videos.
    post_groups.append({
        "title":
        "A Bill a Minute",
        "link":
        "https://www.youtube.com/govtrack",
        "link_text":
        "See all videos on YouTube",
        "posts": [
            {
                "url": "https://www.youtube.com/watch?v=" + video["videoId"],
                "title": video["title"],
                "snippet": video["description"],
                "published": video["publishedAt"],
                "image_url": video["thumbnails"]["medium"]["url"],
            } for video in get_youtube_videos("UCL1f7AGknZWFmXWv6bpJzXg",
                                              limit=3)
            [0:3]  # that's https://www.youtube.com/govtrack
        ]
    })

    # Fetch our Medium posts for summaries and features.
    from website.models import MediumPost
    post_groups.append({
        "title":
        "What We're Watching",
        "posts":
        MediumPost.objects.order_by('-published')[0:3],
        "link":
        "/events/govtrack-insider",
        "link_text":
        "Subscribe to all GovTrack Insider articles",
    })

    # legislation coming up
    from django.db.models import F
    from django.conf import settings
    from bill.models import Bill
    dhg_bills = Bill.objects.filter(
        congress=settings.CURRENT_CONGRESS,
        docs_house_gov_postdate__gt=datetime.now() -
        timedelta(days=10)).filter(
            docs_house_gov_postdate__gt=F('current_status_date'))
    sfs_bills = Bill.objects.filter(
        congress=settings.CURRENT_CONGRESS,
        senate_floor_schedule_postdate__gt=datetime.now() -
        timedelta(days=5)).filter(
            senate_floor_schedule_postdate__gt=F('current_status_date'))
    coming_up = list((dhg_bills | sfs_bills))
    coming_up.sort(key=lambda bill: -bill.proscore())
    if len(coming_up) > 0:
        post_groups.append({
            "title":
            "Legislation Coming Up",
            "posts": [{
                "image_url":
                bill.get_thumbnail_url_ex(),
                "title":
                bill.title,
                "url":
                bill.get_absolute_url(),
                "published":
                "week of " + bill.scheduled_consideration_date.strftime("%x"),
            } for bill in coming_up[0:3]],
            "link":
            "/congress/bills",
            "link_text":
            "View All",
        })

    # trending feeds
    trending_feeds = [
        Feed.objects.get(id=f) for f in Feed.get_trending_feeds()[0:6]
    ]
    if len(trending_feeds) > 0:
        post_groups.append({
            "title":
            "Trending",
            "posts": [{
                "title": feed.title,
                "url": feed.link,
            } for feed in trending_feeds]
        })

    from person.models import Person
    from vote.models import Vote
    return {
        # for the action area below the splash
        'bill_subject_areas': bill_subject_areas,

        # for the highlights blocks
        'post_groups': post_groups,
    }
示例#11
0
def template_context_processor(request):
    # These are good to have in a context processor and not middleware
    # because they won't be evaluated until template evaluation, which
    # might have user-info blocked already for caching (a good thing).
    
    context = {
        "SITE_ROOT_URL": settings.SITE_ROOT_URL,
        "GOOGLE_ANALYTICS_KEY": settings.GOOGLE_ANALYTICS_KEY,
        "STATE_CHOICES": sorted([(kv[0], kv[1], us.stateapportionment[kv[0]]) for kv in us.statenames.items() if kv[0] in us.stateapportionment], key = lambda kv : kv[1]),
    }
    
    if hasattr(request, 'user') and request.user.is_authenticated() and BouncedEmail.objects.filter(user=request.user).exists(): context["user_has_bounced_mail"] = True
    
    # Add top-tracked feeds.
    from events.models import Feed
    global trending_feeds
    if settings.DEBUG and False:
        trending_feeds = [None, []]
    elif not trending_feeds or trending_feeds[0] < datetime.datetime.now()-datetime.timedelta(hours=2):
        trf = cache.get("trending_feeds")
        if not trf:
            trf = Feed.get_trending_feeds()
            cache.set("trending_feeds", trf, 60*60*2)
        trending_feeds = (datetime.datetime.now(), [Feed.objects.get(id=f) for f in trf])
    context["trending_feeds"] = trending_feeds[1]
    context["trending_bill_feeds"] = [f for f in trending_feeds[1] if f.feedname.startswith("bill:")]

    # Add site-wide tracked events.
    all_tracked_events = cache.get("all_tracked_events")
    if not all_tracked_events:
        all_tracked_events = Feed.get_events_for([fn for fn in ("misc:activebills2", "misc:billsummaries", "misc:allvotes") if Feed.objects.filter(feedname=fn).exists()], 6)
        cache.set("all_tracked_events", all_tracked_events, 60*15) # 15 minutes
    context["all_tracked_events"] = all_tracked_events

    # Highlight a recent vote. We don't yet need to know the user's district
    # --- that will happen client-side.
    def get_highlighted_vote():
        from vote.models import Vote, VoteCategory
        candidate_votes = Vote.objects.filter(category__in=Vote.MAJOR_CATEGORIES).exclude(related_bill=None).order_by('-created')
        for v in candidate_votes:
            return { "title": v.question, "link": v.get_absolute_url(), "data": v.simple_record() }
        return "NONE"
    highlighted_vote = cache.get("highlighted_vote")
    if highlighted_vote is None:
        highlighted_vote = get_highlighted_vote()
        cache.set("highlighted_vote", highlighted_vote, 60*60*2)
    if highlighted_vote != "NONE":
        context["highlighted_vote"] = highlighted_vote

    # Get our latest Medium posts.
    def get_medium_posts():
        medium_posts = urllib.urlopen("https://medium.com/govtrack-insider?format=json").read()
        # there's some crap before the JSON object starts
        medium_posts = medium_posts[medium_posts.index("{"):]
        medium_posts = json.loads(medium_posts)
        def format_post(postid):
            post = medium_posts['payload']['references']['Post'][postid]
            collection = medium_posts['payload']['references']['Collection'][post['homeCollectionId']]
            return {
                "title": post['title'],
                "url": "https://medium.com/" + collection['slug'] + "/" + post['uniqueSlug'],
                "date": post['virtuals']['firstPublishedAtEnglish'],
                "preview": post['virtuals']['snippet'],
                "image": post['virtuals']['previewImage']['imageId'] if post['virtuals'].get('previewImage') else None,
                #"preview": " ".join([
                #    para['text']
                #    for para in post['previewContent']['bodyModel']['paragraphs']
                #    if para['type'] == 1 # not sure but a paragraph? vs a heading?
                #])
            }
        return [ format_post(postid) for postid in medium_posts['payload']['value']['sections'][1]['postListMetadata']['postIds'] ]
    medium_posts = cache.get("medium_posts")
    if not medium_posts:
        try:
            medium_posts = get_medium_posts()
        except:
            medium_posts = []
        cache.set("medium_posts", medium_posts, 60*15) # 15 minutes
    context["medium_posts"] = medium_posts[0:3]
    
    # Add context variables for whether the user is in the
    # House or Senate netblocks.
    
    def ip_to_quad(ip):
        return [int(s) for s in ip.split(".")]
    def compare_ips(ip1, ip2):
        return cmp(ip_to_quad(ip1), ip_to_quad(ip2))
    def is_ip_in_range(ip, block):
       return compare_ips(ip, block[0]) >= 0 and compare_ips(ip, block[1]) <= 0
    def is_ip_in_any_range(ip, blocks):
       for block in blocks:
           if is_ip_in_range(ip, block):
               return True
       return False
    
    try:
        ip = request.META["REMOTE_ADDR"]
        ip = ip.replace("::ffff:", "") # ipv6 wrapping ipv4
        
        if is_ip_in_any_range(ip, HOUSE_NET_RANGES):
            context["remote_net_house"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, SENATE_NET_RANGES):
            context["remote_net_senate"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, EOP_NET_RANGES):
            context["remote_net_eop"] = True
            request._track_this_user = True
    except:
        pass
    
    # Add a context variable for if the user is near DC geographically.

    user_loc = None
    try:
        if settings.GEOIP_DB_PATH and not request.path.startswith("/api/"):
            user_loc = geo_ip_db.geos(ip)
            context["is_dc_local"] = user_loc.distance(washington_dc) < .5
    except:
        pass

    if not hasattr(request, 'user') or not request.user.is_authenticated():
        # Have we put the user's district in a cookie?
        try:
            cong_dist = json.loads(request.COOKIES["cong_dist"])
            x = cong_dist["state"] # validate fields are present
            x = int(cong_dist["district"]) # ...and valid
        except:
            cong_dist = None

        # Geolocate to a congressional district if not known and save it in
        # a cookie for next time.
        if user_loc and not cong_dist and not request.path.startswith("/api/"):
            try:
                from person.views import do_district_lookup
                cong_dist = do_district_lookup(*user_loc.coords)
                x = cong_dist["state"] # validate fields are present
                x = int(cong_dist["district"]) # ...and valid
                request._save_cong_dist = cong_dist
            except:
                cong_dist = None

    else:
        # If the user is logged in, is the district in the user's profile?
        profile = request.user.userprofile()
        if profile.congressionaldistrict != None:
            # pass through XX00 so site knows not to prompt
            cong_dist = { "state": profile.congressionaldistrict[0:2], "district": int(profile.congressionaldistrict[2:]) }
        else:
            cong_dist = None

    # If we have a district, get its MoCs.
    if cong_dist:
        from person.models import Person
        context["congressional_district"] = json.dumps(cong_dist)
        context["congressional_district_mocs"] = json.dumps([p.id for p in Person.from_state_and_district(cong_dist["state"], cong_dist["district"])])

    return context
示例#12
0
def template_context_processor(request):
    # These are good to have in a context processor and not middleware
    # because they won't be evaluated until template evaluation, which
    # might have user-info blocked already for caching (a good thing).
    
    context = dict(base_context) # clone
    
    # Add top-tracked feeds.
    from events.models import Feed
    global trending_feeds
    if settings.DEBUG and False:
        trending_feeds = [None, []]
    elif not trending_feeds or trending_feeds[0] < datetime.datetime.now()-datetime.timedelta(hours=2):
        trf = cache.get("trending_feeds")
        if not trf:
            trf = Feed.get_trending_feeds()
            cache.set("trending_feeds", trf, 60*60*2)
        trending_feeds = (datetime.datetime.now(), [Feed.objects.get(id=f) for f in trf])
    context["trending_feeds"] = trending_feeds[1]
    context["trending_bill_feeds"] = [f for f in trending_feeds[1] if f.feedname.startswith("bill:")]

    # Add site-wide tracked events.
    all_tracked_events = cache.get("all_tracked_events")
    if not all_tracked_events:
        all_tracked_events = Feed.get_events_for([fn for fn in ("misc:activebills2", "misc:billsummaries", "misc:allvotes") if Feed.objects.filter(feedname=fn).exists()], 6)
        cache.set("all_tracked_events", all_tracked_events, 60*15) # 15 minutes
    context["all_tracked_events"] = all_tracked_events

    # Get our latest Medium posts.
    medium_posts = cache.get("medium_posts")
    if not medium_posts:
        from website.models import MediumPost
        medium_posts = MediumPost.objects.order_by('-published')[0:6]
        cache.set("medium_posts", medium_posts, 60*15) # 15 minutes
    context["medium_posts"] = medium_posts

    # Add context variables for whether the user is in the
    # House or Senate netblocks.
    
    def ip_to_quad(ip):
        return [int(s) for s in ip.split(".")]
    def compare_ips(ip1, ip2):
        return cmp(ip_to_quad(ip1), ip_to_quad(ip2))
    def is_ip_in_range(ip, block):
       return compare_ips(ip, block[0]) >= 0 and compare_ips(ip, block[1]) <= 0
    def is_ip_in_any_range(ip, blocks):
       for block in blocks:
           if is_ip_in_range(ip, block):
               return True
       return False
    
    try:
        ip = request.META["REMOTE_ADDR"]
        ip = ip.replace("::ffff:", "") # ipv6 wrapping ipv4
        
        if is_ip_in_any_range(ip, HOUSE_NET_RANGES):
            context["remote_net_house"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, SENATE_NET_RANGES):
            context["remote_net_senate"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, EOP_NET_RANGES):
            context["remote_net_eop"] = True
            request._track_this_user = True
    except:
        pass
    
    return context
示例#13
0
def index(request):
    # Fetch subject areas for drop-down.
    from bill.views import subject_choices
    bill_subject_areas = subject_choices()

    post_groups = []
    MAX_PER_GROUP = 3

    # Trending feeds. These are short (no image, no snippet) so they go first.
    trending_feeds = [
        Feed.objects.get(id=f) for f in Feed.get_trending_feeds()[0:6]
    ]
    if len(trending_feeds) > 0:
        post_groups.append({
            "title":
            "Trending",
            "posts": [{
                "title": feed.title,
                "url": feed.link,
            } for feed in trending_feeds],
            "compact":
            True
        })

    # Fetch our latest Medium posts and YouTube videos. Since we publish them in the same
    # work cycle, we can intermix and expect the most recent few to alternate between them.
    # But we only get one link at the bottom.
    from website.models import MediumPost
    post_groups.append({
        "title":
        "What We’re Watching",
        "links":
        [("/events/govtrack-insider",
          "Subscribe to all GovTrack Insider articles"),
         ("https://www.youtube.com/govtrack", "See all videos on YouTube")],
        "posts":
        list(MediumPost.objects.order_by('-published')[0:MAX_PER_GROUP]) + [
            {
                "url":
                "https://www.youtube.com/watch?v=" + video["videoId"],
                "title":
                video["title"].replace("GovTrack A Bill A Minute: ",
                                       "").replace("&amp;",
                                                   "&"),  # !, snippet too?
                "snippet":
                video["description"],
                "published":
                datetime.strptime(video["publishedAt"], '%Y-%m-%dT%H:%M:%SZ'),
                "image_url":
                video["thumbnails"]["medium"]["url"],
            } for video in get_youtube_videos(
                "UCL1f7AGknZWFmXWv6bpJzXg",
                limit=MAX_PER_GROUP)  # that's https://www.youtube.com/govtrack
        ]
    })
    post_groups[-1]["posts"].sort(key=lambda p: p["published"]
                                  if isinstance(p, dict) else p.published,
                                  reverse=True)

    # Legislation coming up. Sadly this is usually the least interesting.
    from django.db.models import F
    from django.conf import settings
    from bill.models import Bill
    dhg_bills = Bill.objects.filter(
        congress=settings.CURRENT_CONGRESS,
        docs_house_gov_postdate__gt=datetime.now() -
        timedelta(days=10)).filter(
            docs_house_gov_postdate__gt=F('current_status_date'))
    sfs_bills = Bill.objects.filter(
        congress=settings.CURRENT_CONGRESS,
        senate_floor_schedule_postdate__gt=datetime.now() -
        timedelta(days=5)).filter(
            senate_floor_schedule_postdate__gt=F('current_status_date'))
    coming_up = list((dhg_bills | sfs_bills))
    coming_up.sort(key=lambda bill: -bill.proscore())
    if len(coming_up) > 0:
        post_groups.append({
            "title":
            "Legislation Coming Up",
            "posts": [{
                "image_url":
                bill.get_thumbnail_url_ex(),
                "title":
                bill.title,
                "url":
                bill.get_absolute_url(),
                "published":
                "week of " + bill.scheduled_consideration_date.strftime("%x"),
            } for bill in coming_up[0:6]],
            "links": [("/congress/bills", "View All")],
        })

    from person.models import Person
    from vote.models import Vote
    return {
        # for the action area below the splash
        'bill_subject_areas': bill_subject_areas,

        # for the highlights blocks
        'post_groups': post_groups,
    }
示例#14
0
def template_context_processor(request):
    # These are good to have in a context processor and not middleware
    # because they won't be evaluated until template evaluation, which
    # might have user-info blocked already for caching (a good thing).

    context = {
        "SITE_ROOT_URL":
        settings.SITE_ROOT_URL,
        "GOOGLE_ANALYTICS_KEY":
        settings.GOOGLE_ANALYTICS_KEY,
        "STATE_CHOICES":
        sorted([(kv[0], kv[1], us.stateapportionment[kv[0]])
                for kv in us.statenames.items()
                if kv[0] in us.stateapportionment],
               key=lambda kv: kv[1]),
    }

    if hasattr(request, 'user') and request.user.is_authenticated(
    ) and BouncedEmail.objects.filter(user=request.user).exists():
        context["user_has_bounced_mail"] = True

    # Add top-tracked feeds.
    global trending_feeds
    if settings.DEBUG:
        trending_feeds = [None, []]
    elif not trending_feeds or trending_feeds[0] < datetime.datetime.now(
    ) - datetime.timedelta(hours=2):
        from events.models import Feed
        trf = cache.get("trending_feeds")
        if not trf:
            trf = Feed.get_trending_feeds()
            cache.set("trending_feeds", trf, 60 * 60 * 2)
        trending_feeds = (datetime.datetime.now(),
                          [Feed.objects.get(id=f) for f in trf])
    context["trending_feeds"] = trending_feeds[1]

    # Highlight a recent vote. We don't yet need to know the user's district
    # --- that will happen client-side.
    def get_highlighted_vote():
        from vote.models import Vote, VoteCategory
        candidate_votes = Vote.objects.filter(
            category__in=Vote.MAJOR_CATEGORIES).exclude(
                related_bill=None).order_by('-created')
        for v in candidate_votes:
            return {
                "title": v.question,
                "link": v.get_absolute_url(),
                "data": v.simple_record()
            }
        return "NONE"

    highlighted_vote = cache.get("highlighted_vote")
    if highlighted_vote is None:
        highlighted_vote = get_highlighted_vote()
        cache.set("highlighted_vote", highlighted_vote, 60 * 60 * 2)
    if highlighted_vote != "NONE":
        context["highlighted_vote"] = highlighted_vote

    # Add context variables for whether the user is in the
    # House or Senate netblocks.

    def ip_to_quad(ip):
        return [int(s) for s in ip.split(".")]

    def compare_ips(ip1, ip2):
        return cmp(ip_to_quad(ip1), ip_to_quad(ip2))

    def is_ip_in_range(ip, block):
        return compare_ips(ip, block[0]) >= 0 and compare_ips(ip,
                                                              block[1]) <= 0

    def is_ip_in_any_range(ip, blocks):
        for block in blocks:
            if is_ip_in_range(ip, block):
                return True
        return False

    try:
        ip = request.META["REMOTE_ADDR"]
        ip = ip.replace("::ffff:", "")  # ipv6 wrapping ipv4

        if is_ip_in_any_range(ip, HOUSE_NET_RANGES):
            context["remote_net_house"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, SENATE_NET_RANGES):
            context["remote_net_senate"] = True
            request._track_this_user = True
        if is_ip_in_any_range(ip, EOP_NET_RANGES):
            context["remote_net_eop"] = True
            request._track_this_user = True
    except:
        pass

    # Add a context variable for if the user is near DC geographically.

    user_loc = None
    try:
        if settings.GEOIP_DB_PATH and not request.path.startswith("/api/"):
            user_loc = geo_ip_db.geos(ip)
            context["is_dc_local"] = user_loc.distance(washington_dc) < .5
    except:
        pass

    if not hasattr(request, 'user') or not request.user.is_authenticated():
        # Have we put the user's district in a cookie?
        try:
            cong_dist = json.loads(request.COOKIES["cong_dist"])
            x = cong_dist["state"]  # validate fields are present
            x = int(cong_dist["district"])  # ...and valid
        except:
            cong_dist = None

        # Geolocate to a congressional district if not known and save it in
        # a cookie for next time.
        if user_loc and not cong_dist and not request.path.startswith("/api/"):
            try:
                from person.views import do_district_lookup
                cong_dist = do_district_lookup(*user_loc.coords)
                x = cong_dist["state"]  # validate fields are present
                x = int(cong_dist["district"])  # ...and valid
                request._save_cong_dist = cong_dist
            except:
                cong_dist = None

    else:
        # If the user is logged in, is the district in the user's profile?
        profile = request.user.userprofile()
        if profile.congressionaldistrict != None:
            # pass through XX00 so site knows not to prompt
            cong_dist = {
                "state": profile.congressionaldistrict[0:2],
                "district": int(profile.congressionaldistrict[2:])
            }
        else:
            cong_dist = None

    # If we have a district, get its MoCs.
    if cong_dist:
        from person.models import Person
        context["congressional_district"] = json.dumps(cong_dist)
        context["congressional_district_mocs"] = json.dumps([
            p.id for p in Person.from_state_and_district(
                cong_dist["state"], cong_dist["district"])
        ])

    return context