Example #1
0
def push_to_social_media_rss(request):
    import django.contrib.syndication.views
    from events.models import Feed
    from events.templatetags.events_utils import render_event
    import re
    
    feedlist = [Feed.from_name("misc:comingup"), Feed.from_name('misc:enactedbills')]
    
    class DjangoFeed(django.contrib.syndication.views.Feed):
        title = "GovTrack.us Is Tracking Congress"
        link = "/"
        description = "GovTrack tracks the activities of the United States Congress. We push this feed to our Twitter and Facebook accounts."
        
        def items(self):
            events = [render_event(item, feedlist) for item in Feed.get_events_for(feedlist, 25)]
            return [e for e in events if e != None]
            
        def item_title(self, item):
            return re.sub(r"^Legislation ", "", item["type"]) + ": " + item["title"]
        def item_description(self, item):
            return item["body_text"]
        def item_link(self, item):
            return settings.SITE_ROOT_URL + item["url"]# + "?utm_campaign=govtrack_push&utm_source=govtrack_push" 
        def item_guid(self, item):
            return "http://www.govtrack.us/events/guid/" + item["guid"] 
        def item_pubdate(self, item):
            return item["date"] if isinstance(item["date"], datetime) or item["date"] is None else datetime.combine(item["date"], time.min)
            
    return DjangoFeed()(request)
Example #2
0
def push_to_social_media_rss(request):
    import django.contrib.syndication.views
    from events.models import Feed
    from events.templatetags.events_utils import render_event
    import re
    
    feedlist = [Feed.from_name("misc:comingup"), Feed.from_name('misc:enactedbills')]
    
    class DjangoFeed(django.contrib.syndication.views.Feed):
        title = "GovTrack.us Is Tracking Congress"
        link = "/"
        description = "GovTrack tracks the activities of the United States Congress. We push this feed to our Twitter and Facebook accounts."
        
        def items(self):
            events = [render_event(item, feedlist) for item in Feed.get_events_for(feedlist, 25)]
            return [e for e in events if e != None]
            
        def item_title(self, item):
            return re.sub(r"^Legislation ", "", item["type"]) + ": " + item["title"]
        def item_description(self, item):
            return item["body_text"]
        def item_link(self, item):
            return "http://www.govtrack.us" + item["url"]# + "?utm_campaign=govtrack_push&utm_source=govtrack_push" 
        def item_guid(self, item):
            return "http://www.govtrack.us/events/guid/" + item["guid"] 
        def item_pubdate(self, item):
            return item["date"] if isinstance(item["date"], datetime) or item["date"] is None else datetime.combine(item["date"], time.min)
            
    return DjangoFeed()(request)
Example #3
0
 def create_event(self):
     if self.congress < 111: return # not interested, creates too much useless data and slow to load
     from events.models import Feed, Event
     with Event.update(self) as E:
         E.add("vote", self.created, Feed.AllVotesFeed())
         for v in self.voters.all():
             if v.person_id:
                 E.add("vote", self.created, Feed.PersonVotesFeed(v.person_id))
Example #4
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]

        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,
            "subjects": subject_choices(),
            "BILL_STATUS_INTRO": (BillStatus.introduced, BillStatus.reported),
        }
Example #5
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
Example #6
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)
        coming_up.sort(key = lambda b : b.docs_house_gov_postdate if (b.docs_house_gov_postdate and (not b.senate_floor_schedule_postdate or b.senate_floor_schedule_postdate < b.docs_house_gov_postdate)) else b.senate_floor_schedule_postdate, reverse=True)

        # 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]

        # current congrss years
        start, end = get_congress_dates(CURRENT_CONGRESS)
        end_year = end.year if end.month > 1 else end.year-1 # count January finishes as the prev year
        current_congress_years = '%d-%d' % (start.year, end.year)
        current_congress = ordinal(CURRENT_CONGRESS)

        return {
            "feeds": feeds,

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

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

            "subjects": subject_choices(),
            "BILL_STATUS_INTRO": (BillStatus.introduced, BillStatus.referred, BillStatus.reported),
        }
Example #7
0
 def create_events(self):
     from events.models import Feed, Event
     feeds = [
         Feed.AllCommitteesFeed(),
         Feed.CommitteeMeetingsFeed(self.code)
     ]
     if self.committee:
         feeds.append(Feed.CommitteeMeetingsFeed(
             self.committee.code))  # add parent committee
     with Event.update(self) as E:
         for meeting in self.meetings.all():
             E.add("mtg_" + str(meeting.id), meeting.when,
                   feeds + [Feed.BillFeed(b) for b in meeting.bills.all()])
Example #8
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),
        }
Example #9
0
def export_panel_user_data(request, panel_id, download):
    import csv, io
    from django.utils.text import slugify
    from website.models import UserPosition
    from bill.models import Bill
    from events.models import Feed

    panel = get_object_or_404(Panel, id=panel_id, admins=request.user)

    buf = io.BytesIO()
    w = csv.writer(buf)

    if download == "members":
        # Download the panel's membership, with one row per member.
        w.writerow(["id", "email", "joined", "invitation_code", "notes"])
        for mbr in PanelMembership.objects.filter(
                panel=panel).order_by('created').select_related("user"):
            w.writerow([
                mbr.id,
                mbr.user.email,
                mbr.created,
                mbr.invitation_code,
                mbr.extra.get("notes", ""),
            ])
    elif download == "positions":
        # Download the positions panel members have taken on legislation,
        # with one row per member-position.
        members = dict(
            PanelMembership.objects.filter(panel=panel).values_list(
                "user_id", "id"))
        w.writerow([
            "position_id", "member_id", "member_email", "position_created",
            "bill_id", "bill_title", "bill_link", "likert_score", "reason_text"
        ])
        for upos in UserPosition.objects.filter(user__in=members)\
            .order_by('created')\
            .select_related("user"):
            w.writerow([
                upos.id,
                members[upos.user.id],
                upos.user.email,
                upos.created,
                Bill.from_feed(Feed.from_name(
                    upos.subject)).congressproject_id,
                upos.get_subject_title().encode("utf8"),
                "https://www.govtrack.us" + upos.get_subject_link(),
                upos.likert,
                upos.reason.encode("utf8"),
            ])
    else:
        return HttpResponse("invalid")

    ret = HttpResponse(buf.getvalue())
    if True:  # disable to make debugging easier
        ret["Content-Type"] = "text/csv"
        ret["Content-Disposition"] = "attachment;filename=%s_%s.csv" % (
            slugify(panel.title), download)
    else:
        ret["Content-Type"] = "text/plain"
    return ret
Example #10
0
def homepage_summary(request):
	# parse & validate parameters
	try:
		state = request.GET["district"][0:2]
		district = int(request.GET["district"][2:])
		if state not in statenames: raise Exception()
	except:
		return None

	from django.contrib.humanize.templatetags.humanize import ordinal

	# view
	people = Person.from_state_and_district(state, district)
	feeds = [p.get_feed() for p in people]
	events = Feed.get_events_for(feeds, 6)

	from events.templatetags.events_utils import render_event
	for i in range(len(events)):
		events[i] = render_event(events[i], feeds)
		if not isinstance(events[i]["date"], str):
			events[i]["date"] = events[i]["date"].strftime('%B %d, %Y') # can't JSON-serialize a datetime anyway, TODO handle date_has_no_time
		for k in list(events[i]): # remove anything else in case it is not JSON-serializable
			if k not in ('type', 'date', 'title', 'body_html', 'url'):
				del events[i][k]

	# form output
	return {
		"state": state,
		"district": district,
		"state_name": statenames[state],
		"district_ordinal": ordinal(district),
		"reps": [ { "link": p.get_absolute_url(), "name": p.name_and_title(), "title": p.role.get_description(), "photo": p.get_photo_url() } for p in people],
		"events": events,
	}
Example #11
0
 def build_info():
     feeds = [f for f in Feed.get_simple_feeds() if f.category == "federal-bills"]
     
     groups = [
         (   g[0], # title
             g[1], # text 1
             g[2], # text 2
             "/congress/bills/browse?status=" + ",".join(str(s) for s in g[4]), # 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 ]
         
     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)
     coming_up.sort(key = lambda b : b.docs_house_gov_postdate if (b.docs_house_gov_postdate and (not b.senate_floor_schedule_postdate or b.senate_floor_schedule_postdate < b.docs_house_gov_postdate)) else b.senate_floor_schedule_postdate, reverse=True)
     
     start, end = get_congress_dates(CURRENT_CONGRESS)
     end_year = end.year if end.month > 1 else end.year-1 # count January finishes as the prev year
     current_congress_years = '%d-%d' % (start.year, end.year)
     current_congress = ordinal(CURRENT_CONGRESS)
     
     return {
         "feeds": feeds,
         
         "total": Bill.objects.filter(congress=CURRENT_CONGRESS).count(),
         "current_congress_years": current_congress_years,
         "current_congress": current_congress,
         "groups": groups,
         "coming_up": coming_up,
         "subjects": subject_choices(),
         "BILL_STATUS_INTRO": (BillStatus.introduced, BillStatus.referred, BillStatus.reported),
     }
Example #12
0
    def build_info():
        feeds = [f for f in Feed.get_simple_feeds() if f.category == "federal-bills"]

        groups = [
            (   g[0], # title
                g[1], # text 1
                g[2], # text 2
                "/congress/bills/browse?status=" + ",".join(str(s) for s in g[4]), # 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 ]

        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)
        coming_up.sort(key = lambda b : b.docs_house_gov_postdate if (b.docs_house_gov_postdate and (not b.senate_floor_schedule_postdate or b.senate_floor_schedule_postdate < b.docs_house_gov_postdate)) else b.senate_floor_schedule_postdate, reverse=True)

        start, end = get_congress_dates(CURRENT_CONGRESS)
        end_year = end.year if end.month > 1 else end.year-1 # count January finishes as the prev year
        current_congress_years = '%d-%d' % (start.year, end.year)
        current_congress = ordinal(CURRENT_CONGRESS)

        return {
            "feeds": feeds,

            "total": Bill.objects.filter(congress=CURRENT_CONGRESS).count(),
            "current_congress_years": current_congress_years,
            "current_congress": current_congress,
            "groups": groups,
            "coming_up": coming_up,
            "subjects": subject_choices(),
            "BILL_STATUS_INTRO": (BillStatus.introduced, BillStatus.referred, BillStatus.reported),
        }
Example #13
0
def index(request):
    twitter_feed = cache.get("our_twitter_feed")
    if twitter_feed == None:
        try:
            import twitter
            twitter_api = twitter.Api()
            twitter_feed = twitter_api.GetUserTimeline("govtrack", since_id=0, count=3)
        
            # replace links
            from django.utils.html import conditional_escape
            from django.utils.safestring import mark_safe
            re_url = re.compile(r"(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))")
            for item in twitter_feed:
                item.text = re_url.sub(lambda m : "<a target=\"_blank\" href=\"" + m.group(0) + "\">" + m.group(0) + "</a>", conditional_escape(item.text))
            cache.set("our_twitter_feed", twitter_feed, 60*30) # 30 minutes
        except:
            twitter_feed = []
            cache.set("our_twitter_feed", twitter_feed, 60*2) # 2 minutes
            
        
    blog_feed = cache.get("our_blog_feed")
    if not blog_feed:
        blog_feed = get_blog_items()[0:2]
        cache.set("our_blog_feed", blog_feed, 60*30) # 30 min
    
    events_feed = cache.get("frontpage_events_feed")
    if not events_feed:
        events_feed = Feed.get_events_for([fn for fn in ("misc:activebills2", "misc:billsummaries", "misc:allvotes") if Feed.objects.filter(feedname=fn).exists()], 6)
        cache.set("frontpage_events_feed", events_feed, 60*15) # 15 minutes

    return {
        'events': events_feed,
        'tweets': twitter_feed,
        'blog': blog_feed,
        }
Example #14
0
def bill_details_user_view(request, congress, type_slug, number):
    bill = load_bill_from_url(congress, type_slug, number)

    ret = { }
    if request.user.is_staff:
        admin_panel = """
            {% load humanize %}
            <div class="clear"> </div>
            <div style="margin-top: 1.5em; padding: .5em; background-color: #EEE; ">
                <b>ADMIN</b> - <a href="{% url "bill_go_to_summary_admin" %}?bill={{bill.id}}">Edit Summary</a>
                <br/>Tracked by {{feed.tracked_in_lists.count|intcomma}} users
                ({{feed.tracked_in_lists_with_email.count|intcomma}} w/ email).
            </div>
            """
        from django.template import Template, Context, RequestContext, loader
        ret["admin_panel"] = Template(admin_panel).render(RequestContext(request, {
            'bill': bill,
            "feed": Feed.BillFeed(bill),
            }))

    from person.views import render_subscribe_inline
    ret.update(render_subscribe_inline(request, Feed.BillFeed(bill)))

    # poll_and_call
    if request.user.is_authenticated():
        from poll_and_call.models import RelatedBill as IssueByBill, UserPosition
        try:
            issue = IssueByBill.objects.get(bill=bill).issue
            try:
                up = UserPosition.objects.get(user=request.user, position__issue=issue)
                targets = up.get_current_targets()
                ret["poll_and_call_position"] =  {
                    "id": up.position.id,
                    "text": up.position.text,
                    "can_change": up.can_change_position(),
                    "can_call": [(t.id, t.person.name) for t in targets] if isinstance(targets, list) else [],
                    "call_url": issue.get_absolute_url() + "/make_call",
                }
            except UserPosition.DoesNotExist:
                pass
        except IssueByBill.DoesNotExist:
            pass
        
    return ret
Example #15
0
 def create_events(self, prev_role, next_role):
     now = datetime.datetime.now().date()
     from events.models import Feed, Event
     with Event.update(self) as E:
         f = Feed.PersonFeed(self.person_id)
         if not prev_role or not self.continues_from(prev_role):
             E.add("termstart", self.startdate, f)
         if not next_role or not next_role.continues_from(self):
             if self.enddate <= now:  # because we're not sure of end date until it happens
                 E.add("termend", self.enddate, f)
Example #16
0
def export_panel_user_data(request, panel_id, download):
    import csv, io
    from django.utils.text import slugify
    from website.models import UserPosition
    from bill.models import Bill
    from events.models import Feed

    panel = get_object_or_404(Panel, id=panel_id, admins=request.user)

    buf = io.StringIO()
    w = csv.writer(buf)

    if download == "members":
        # Download the panel's membership, with one row per member.
        w.writerow(["id", "email", "joined", "invitation_code", "notes"])
        for mbr in PanelMembership.objects.filter(panel=panel).order_by('created').select_related("user"):
            w.writerow([
                str(mbr.id),
                mbr.user.email,
                mbr.created.isoformat(),
                mbr.invitation_code,
                mbr.extra.get("notes", ""),
            ])
    elif download == "positions":
        # Download the positions panel members have taken on legislation,
        # with one row per member-position.
        members = dict(PanelMembership.objects.filter(panel=panel).values_list("user_id", "id"))
        w.writerow(["position_id", "member_id", "member_email", "position_created", "bill_id", "bill_title", "bill_link", "likert_score", "reason_text"])
        for upos in UserPosition.objects.filter(user__in=members)\
            .order_by('created')\
            .select_related("user"):
            w.writerow([
                str(upos.id),
                members[upos.user.id],
                upos.user.email,
                upos.created.isoformat(),
                Bill.from_feed(Feed.from_name(upos.subject)).congressproject_id,
                upos.get_subject_title(),
                "https://www.govtrack.us" + upos.get_subject_link(),
                str(upos.likert),
                upos.reason,
            ])
    else:
        return HttpResponse("invalid")
    
    ret = HttpResponse(buf.getvalue())
    if True: # disable to make debugging easier
        ret["Content-Type"] = "text/csv"
        ret["Content-Disposition"] = "attachment;filename=%s_%s.csv" % (
            slugify(panel.title),
            download
        )
    else:
        ret["Content-Type"] = "text/plain"
    return ret
	def handle(self, *args, **options):
		# get feeds, across all congresses
		top_bills = Feed.objects.annotate(count=Count('tracked_in_lists'))\
			.filter(feedname__startswith='bill:')\
			.filter(feedname__regex='^bill:[hs][jcr]?%d-' % settings.CURRENT_CONGRESS)\
			.order_by('-count')\
			.values('feedname', 'count')\
			[0:25]

		print "users \t url \t bill title"
		for bf in top_bills:
			b = Feed.from_name(bf["feedname"]).bill()
			print bf["count"], "\t", b.get_absolute_url(), "\t", b
Example #18
0
 def build_info():
     if re.match(r"\d", pk):
         person = get_object_or_404(Person, pk=pk)
     else:
         # support bioguide IDs for me
         person = get_object_or_404(Person, bioguideid=pk)
     
     # current role
     role = person.get_current_role()
     if role:
         active_role = True
     else:
         active_role = False
         try:
             role = person.roles.order_by('-enddate')[0]
         except IndexError:
             role = None
 
     # photo
     photo_path = 'data/photos/%d-100px.jpeg' % person.pk
     photo_credit = None
     if os.path.exists(photo_path):
         photo = '/' + photo_path
         with open(photo_path.replace("-100px.jpeg", "-credit.txt"), "r") as f:
             photo_credit = f.read().strip().split(" ", 1)
     else:
         photo = None
 
     analysis_data = analysis.load_data(person)
     
     links = []
     if person.osid: links.append(("OpenSecrets", "http://www.opensecrets.org/politicians/summary.php?cid=" + person.osid))
     if person.pvsid: links.append(("VoteSmart", "http://votesmart.org/candidate/" + person.pvsid))
     if person.bioguideid: links.append(("Bioguide", "http://bioguide.congress.gov/scripts/biodisplay.pl?index=" + person.bioguideid))
     if person.cspanid: links.append(("C-SPAN Video", "http://www.c-spanvideo.org/person/" + str(person.cspanid)))
 
     return {'person': person,
             'role': role,
             'active_role': active_role,
             'active_congressional_role': active_role and role.role_type in (RoleType.senator, RoleType.representative),
             'photo': photo,
             'photo_credit': photo_credit,
             'links': links,
             'analysis_data': analysis_data,
             'recent_bills': person.sponsored_bills.all().order_by('-introduced_date')[0:7],
             'committeeassignments': get_committee_assignments(person),
             'feed': Feed.PersonFeed(person.id),
             'cities': get_district_cities("%s-%02d" % (role.state.lower(), role.district)) if role and role.district else None,
             }
Example #19
0
def bill_details_user_view(request, congress, type_slug, number):
    bill = load_bill_from_url(congress, type_slug, number)

    ret = { }
    if request.user.is_staff:
        admin_panel = """
            {% load humanize %}
            <div class="clear"> </div>
            <div style="margin-top: 1.5em; padding: .5em; background-color: #EEE; ">
                <b>ADMIN</b> - <a href="{% url "bill_go_to_summary_admin" %}?bill={{bill.id}}">Edit Summary</a>
                <br/>Tracked by {{feed.tracked_in_lists.count|intcomma}} users
                ({{feed.tracked_in_lists_with_email.count|intcomma}} w/ email).
            </div>
            """
        from django.template import Template, Context, RequestContext, loader
        ret["admin_panel"] = Template(admin_panel).render(RequestContext(request, {
            'bill': bill,
            "feed": Feed.BillFeed(bill),
            }))

    from person.views import render_subscribe_inline
    ret.update(render_subscribe_inline(request, Feed.BillFeed(bill)))

    return ret
Example #20
0
def index(request):
    blog_feed = cache.get("our_blog_feed")
    if not blog_feed:
        blog_feed = get_blog_items()[0:4]
        cache.set("our_blog_feed", blog_feed, 60*30) # 30 min
    
    events_feed = cache.get("frontpage_events_feed")
    if not events_feed:
        events_feed = Feed.get_events_for([fn for fn in ("misc:activebills2", "misc:billsummaries", "misc:allvotes") if Feed.objects.filter(feedname=fn).exists()], 6)
        cache.set("frontpage_events_feed", events_feed, 60*15) # 15 minutes

    return {
        'events': events_feed,
        'blog': blog_feed,
        }
Example #21
0
def vote_list(request):
    # Get the default session to show. We may have sessions listed that are
    # in the future, during a transition, so take the most recent that at
    # least has started.
    default_session = None
    for i, (cn, sn, sd, ed) in reversed(list(enumerate(get_all_sessions()))):
        if sd > datetime.now().date(): continue
        if not Vote.objects.filter(congress=cn, session=sn).exists(): continue
        default_session = i
        break
    
    return vote_search_manager().view(request, "vote/vote_list.html",
        defaults = { "session": default_session },
        paginate = lambda form : "session" not in form, # people like to see all votes for a year on one page
        context = { "feed": Feed(feedname="misc:allvotes") })
Example #22
0
def index(request):
    blog_feed = cache.get("our_blog_feed")
    if not blog_feed:
        blog_feed = get_blog_items()[0:4]
        cache.set("our_blog_feed", blog_feed, 60*30) # 30 min
    
    events_feed = cache.get("frontpage_events_feed")
    if not events_feed:
        events_feed = Feed.get_events_for([fn for fn in ("misc:activebills2", "misc:billsummaries", "misc:allvotes") if Feed.objects.filter(feedname=fn).exists()], 6)
        cache.set("frontpage_events_feed", events_feed, 60*15) # 15 minutes

    return {
        'events': events_feed,
        'blog': blog_feed,
        }
	def show_stats(self, recent_users_only):
		# get feeds, across all congresses
		top_bills = Feed.objects\
			.filter(feedname__startswith='bill:')\
			.filter(feedname__regex='^bill:[hs][jcr]?%d-' % settings.CURRENT_CONGRESS)
		if recent_users_only:
			top_bills = top_bills.filter(tracked_in_lists__user__date_joined__gt=datetime.datetime.now()-datetime.timedelta(days=14))
		top_bills = top_bills\
			.annotate(count=Count('tracked_in_lists'))\
			.order_by('-count')\
			.values('feedname', 'count')\
			[0:25]

		print "users \t url \t bill title"
		for bf in top_bills:
			b = Feed.from_name(bf["feedname"]).bill()
			print bf["count"], "\t", b.get_absolute_url(), "\t", b
	def show_stats(self, recent_users_only):
		# get feeds, across all congresses
		top_bills = Feed.objects\
			.filter(feedname__startswith='bill:')\
			.filter(feedname__regex='^bill:[hs][jcr]?%d-' % settings.CURRENT_CONGRESS)
		if recent_users_only:
			top_bills = top_bills.filter(tracked_in_lists__user__date_joined__gt=datetime.datetime.now()-datetime.timedelta(days=14))
		top_bills = top_bills\
			.annotate(count=Count('tracked_in_lists'))\
			.order_by('-count')\
			.values('feedname', 'count')\
			[0:25]

		print("new users \t all users \t sponsor \t url \t bill title")
		for bf in top_bills:
			f = Feed.from_name(bf["feedname"])
			b = Bill.from_feed(f)
			print(bf["count"], "\t", f.tracked_in_lists.all().count(), "\t", b.sponsor.lastname.encode("utf8"), b.get_absolute_url(), "\t", b)
Example #25
0
def update_userposition(request):
    from website.models import UserPosition
    if request.method != "POST": raise HttpResponseBadRequest()

    # just validate
    f = Feed.from_name(request.POST.get("subject", ""))
    f.title

    qs = UserPosition.objects.filter(user=request.user, subject=request.POST["subject"])
    if not request.POST.get("likert") and not request.POST.get("reason"):
        # Nothing to save - delete any existing.
        qs.delete()
    else:
        # Update.
        upos, _ = qs.get_or_create(user=request.user, subject=request.POST["subject"])
        upos.likert = int(request.POST["likert"]) if request.POST.get("likert") else None
        upos.reason = request.POST["reason"]
        upos.save()

    return HttpResponse(json.dumps({ "status": "ok" }), content_type="application/json")
Example #26
0
def update_userposition(request):
    from website.models import UserPosition
    if request.method != "POST": raise HttpResponseBadRequest()

    # just validate
    f = Feed.from_name(request.POST.get("subject", ""))
    f.title

    qs = UserPosition.objects.filter(user=request.user, subject=request.POST["subject"])
    if not request.POST.get("likert") and not request.POST.get("reason"):
        # Nothing to save - delete any existing.
        qs.delete()
    else:
        # Update.
        upos, _ = qs.get_or_create(user=request.user, subject=request.POST["subject"])
        upos.likert = int(request.POST["likert"]) if request.POST.get("likert") else None
        upos.reason = request.POST["reason"]
        upos.save()

    return HttpResponse(json.dumps({ "status": "ok" }), content_type="application/json")
Example #27
0
 def create_events(self):
     if self.congress < 112: return # not interested, creates too much useless data and slow to load
     from events.models import Feed, Event
     with Event.update(self) as E:
         # collect the feeds that we'll add major actions to
         bill_feed = Feed.BillFeed(self)
         index_feeds = [bill_feed]
         if self.sponsor != None:
             index_feeds.append(Feed.PersonSponsorshipFeed(self.sponsor))
         index_feeds.extend([Feed.IssueFeed(ix) for ix in self.terms.all()])
         index_feeds.extend([Feed.CommitteeBillsFeed(cx) for cx in self.committees.all()])
         
         # also index into feeds for any related bills and previous versions of this bill
         # that people may still be tracking
         for rb in self.get_related_bills():
             index_feeds.append(Feed.BillFeed(rb.related_bill))
         for b in self.find_reintroductions():
             index_feeds.append(Feed.BillFeed(b))
         
         # generate events for major actions
         E.add("state:" + str(BillStatus.introduced), self.introduced_date, index_feeds + [Feed.ActiveBillsFeed(), Feed.IntroducedBillsFeed()])
         common_feeds = [Feed.ActiveBillsFeed(), Feed.ActiveBillsExceptIntroductionsFeed()]
         enacted_feed = [Feed.EnactedBillsFeed()]
         for datestr, state, text in self.major_actions:
             date = eval(datestr)
             if state == BillStatus.introduced:
                 continue # already indexed
             if state == BillStatus.referred and (date.date() - self.introduced_date).days == 0:
                 continue # don't dup these events so close
             E.add("state:" + str(state), date, index_feeds + common_feeds + (enacted_feed if state in BillStatus.final_status_passed_bill else []))
             
         # generate events for new cosponsors... group by join date, and
         # assume that join dates we've seen don't have new cosponsors
         # added later, or else we may miss that in an email update. we
         # don't actually need the people listed here, just the unique join
         # dates.
         cosponsor_join_dates = set()
         for cosp in Cosponsor.objects.filter(bill=self, withdrawn=None).exclude(joined=self.introduced_date):
             cosponsor_join_dates.add(cosp.joined)
         for joindate in cosponsor_join_dates:
             E.add("cosp:" + joindate.isoformat(), joindate, [bill_feed])
             
         # generate an event for appearing on docs.house.gov or the senate floor schedule:
         if self.docs_house_gov_postdate:
             E.add("dhg", self.docs_house_gov_postdate, index_feeds + common_feeds + [Feed.ComingUpFeed()])
         if self.senate_floor_schedule_postdate:
             E.add("sfs", self.senate_floor_schedule_postdate, index_feeds + common_feeds + [Feed.ComingUpFeed()])
             
         # generate an event for each new GPO text availability
         from glob import glob
         from billtext import bill_gpo_status_codes
         bt = BillType.by_value(self.bill_type).xml_code
         for st in bill_gpo_status_codes:
             textfn = "data/us/bills.text/%s/%s/%s%d%s.pdf" % (self.congress, bt, bt, self.number, st) # use pdf since we don't modify it once we download it, and hopefully we actually have a displayable format like HTML
             if os.path.exists(textfn):
                 textmodtime = datetime.datetime.fromtimestamp(os.path.getmtime(textfn))
                 E.add("text:" + st, textmodtime, index_feeds)
                 
         # generate an event for the main summary
         bs = BillSummary.objects.filter(bill=self)
         if len(bs) > 0:
             E.add("summary", bs[0].created, index_feeds + [Feed.from_name("misc:billsummaries")])
Example #28
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
Example #29
0
 def items(self):
     events = [
         render_event(item, feedlist)
         for item in Feed.get_events_for(feedlist, 25)
     ]
     return [e for e in events if e != None]
Example #30
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
Example #31
0
 def AllVotesFeed():
     from events.models import Feed
     return Feed.get_noarg_feed("misc:allvotes")
Example #32
0
	    # in other states too, so this would be incorrect for that. But
	    # we'd still like to know what is the current session.
	    if self.enddate == None:
	        # Not sure.
	        self.current = False
	        self.save()
	        return
	    self.current = not StateSession.objects.filter(state=self.state, startdate__gte=self.enddate).exists()
	    self.save()

from events.models import Feed
Feed.register_feed(
	"states_allbills",
	title = "State Legislation: All Activity",
	slug = "states_bills",
	intro_html = """Use this feed to track all legislative events in all United States state legislatures.""",
	simple = True,
	sort_order = 200,
	category = "state-bills",
	description = "Get an update on major activity on all state legislation.",
	)
for st in us.stateabbrs:
	Feed.register_feed(
		"states_%s_bills" % st,
		title = us.statenames[st] + " Legislation",
		link = "/states/%s" % st.lower(),
		category = "state-bills",
		description = "Get an update on major activity on all bills in this state.",
		)
Feed.register_feed(
	"states_bill:",
	title = lambda feed : unicode(StateBill.objects.get(id=feed.feedname.split(":")[1])),
Example #33
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,
        }
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
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
Example #36
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
Example #37
0
 def AllCommitteesFeed():
     from events.models import Feed
     return Feed.get_noarg_feed("misc:allcommittee")
Example #38
0
 def items(self):
     events = [render_event(item, feedlist) for item in Feed.get_events_for(feedlist, 25)]
     return [e for e in events if e != None]
Example #39
0
    def is_recently_added(self):
        return (self.created > (datetime.now() - timedelta(hours=36)))

    def abbrev_committee_name(self):
        return self.committee.sortname(True)


# feeds

from events.models import Feed, truncate_words

Feed.register_feed(
    "misc:allcommittee",
    title="Committee Meetings",
    link="/congress/committees",
    simple=True,
    sort_order=103,
    category="federal-committees",
    description=
    "Get an alert whenever a committee hearing or mark-up session is scheduled.",
)
Feed.register_feed(
    "committee:",
    title=lambda feed: truncate_words(Committee.from_feed(feed).fullname, 12),
    noun="committee",
    includes=lambda feed: [
        Committee.from_feed(feed).get_feed("bills"),
        Committee.from_feed(feed).get_feed("meetings")
    ],
    link=lambda feed: Committee.from_feed(feed).get_absolute_url(),
    scoped_title=lambda feed: "All Events for This Committee",
    is_valid=lambda feed: Committee.from_feed(feed, test=True),
Example #40
0
 def create_events(self):
     from events.models import Feed, Event
     with Event.update(self) as E:
         feeds = [Feed.from_name("misc:govtrackinsider")]
         E.add("post", self.published, feeds)
Example #41
0
 def AllCommitteesFeed():
     from events.models import Feed
     return Feed.get_noarg_feed("misc:allcommittee")
Example #42
0
class VoteSummary(models.Model):
    vote = models.OneToOneField(Vote, related_name="oursummary", on_delete=models.PROTECT)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    content = models.TextField(blank=True)

    def __str__(self): return "Summary for " + str(self.vote)
    def get_absolute_url(self): return self.vote.get_absolute_url()

    def as_html(self):
        return markdown2.markdown(self.content)

    def plain_text(self):
        # Kill links.
        import re
        content = re.sub("\[(.*?)\]\(.*?\)", r"\1", self.content)
        return content

# Feeds
from events.models import Feed
Feed.register_feed(
    "misc:allvotes",
    title = "Roll Call Votes",
    link = "/congress/votes",
    simple = True,
    single_event_type = True,
    sort_order = 101,
    category = "federal-votes",
    description = "You will get an alert for every roll call vote in Congress.",
    )
Example #43
0
        from events.models import Feed, Event
        with Event.update(self) as E:
            feeds = [Feed.from_name("misc:govtrackinsider")]
            E.add("post", self.published, feeds)

    def render_event(self, eventid, feeds):
        return {
            "type": "GovTrack Insider",
            "date": self.published,
            "date_has_no_time": False,
            "title": self.title,
            "url": self.get_absolute_url(),
            "body_text_template": """{{snippet|safe}}""",
            "body_html_template": """<p>{{snippet}}</p>""",
            "context": {
                "snippet": self.snippet,
            }
        }


Feed.register_feed(
    "misc:govtrackinsider",
    title="GovTrack Insider Articles",
    simple=True,
    slug="govtrack-insider",
    intro_html=
    """<p>This feed includes posts on <a href="https://medium.com/govtrack-insider">GovTrack Insider</a>.</p>""",
    description=
    "Get an update whenever we post a new article on GovTrack Insider.",
)
Example #44
0
        if self.party == "Republican": return "Democrat"
        return None

    def get_sort_key(self):
        # As it happens, our enums define a good sort order between senators and representatives.
        return (self.role_type, self.senator_rank)

# Feeds

from events.models import Feed
Feed.register_feed(
    "p:",
    title = lambda feed : Person.from_feed(feed).name,
    noun = "person",
    includes = lambda feed : [Person.from_feed(feed).get_feed("pv"), Person.from_feed(feed).get_feed("ps")],
    link = lambda feed: Person.from_feed(feed).get_absolute_url(),
    scoped_title = lambda feed : "All Events for " + Person.from_feed(feed).lastname,
    category = "federal-other",
    description = "You will get updates about major activity on sponsored bills and how this Member of Congress votes in roll call votes.",
    is_subscribable = lambda feed : Person.from_feed(feed).get_current_role() is not None,
    track_button_noun = lambda feed : Person.from_feed(feed).him_her,
    )
Feed.register_feed(
    "ps:",
    title = lambda feed : Person.from_feed(feed).name + " - Bills Sponsored",
    noun = "person",
    link = lambda feed: Person.from_feed(feed).get_absolute_url(),
    scoped_title = lambda feed : Person.from_feed(feed).lastname + "'s Sponsored Bills",
    category = "federal-bills",
    description = "You will get updates about major activity on bills sponsored by this Member of Congress.",
    )
Feed.register_feed(
Example #45
0
 def create_events(self):
     from events.models import Feed, Event
     with Event.update(self) as E:
         feeds = [Feed.from_name("misc:govtrackinsider")]
         E.add("post", self.published, feeds)
Example #46
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,
    }
Example #47
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
		m = m.replace("$;", ",");
		m = m.replace("$C", ",");
		m = m.replace("$$", "$");
		m = m.replace(r"\\;", ",").replace(r"\;", ",")
		try:
			if m in feed_cache:
				feed = feed_cache[m]
			elif m.startswith("crs:"):
				name = m[4:]
				name = crs_map.get(name, name)
				terms = BillTerm.objects.filter(name=m[4:]).order_by("-term_type") # new first
				if len(terms) > 0:
					feed = Feed.IssueFeed(terms[0])
				else:
					raise ValueError("unknown subject")
			elif m.startswith("committee:"):
				m = m[10:].replace(" Subcommittee", "").replace("  ", " ")
				feed = Feed.CommitteeFeed(Committee.objects.get(code=committee_map[m]))
			else:
				feed = Feed.from_name(m)
			feed_cache[m] = feed
			
			sublist.trackers.add(feed)
			
		except Exception as e:
			#print fields["id"], m, e
			missing_feeds[m] = missing_feeds.get(m, 0) + 1
	
#print sorted((v, k) for k, v in missing_feeds.items())

Example #49
0
    content = models.TextField(blank=True)

    def __str__(self):
        return "Summary for " + str(self.vote)

    def get_absolute_url(self):
        return self.vote.get_absolute_url()

    def as_html(self):
        return markdown2.markdown(self.content)

    def plain_text(self):
        # Kill links.
        import re
        content = re.sub("\[(.*?)\]\(.*?\)", r"\1", self.content)
        return content


# Feeds
from events.models import Feed
Feed.register_feed(
    "misc:allvotes",
    title="Roll Call Votes",
    link="/congress/votes",
    simple=True,
    single_event_type=True,
    sort_order=101,
    category="federal-votes",
    description="You will get an alert for every roll call vote in Congress.",
)
Example #50
0
def bill_search_feed_title(q):
    from search import bill_search_manager
    return "Bill Search - " + bill_search_manager().describe_qs(q)
def bill_search_feed_execute(q):
    from search import bill_search_manager
    from settings import CURRENT_CONGRESS
    
    bills = bill_search_manager().execute_qs(q, overrides={'congress': CURRENT_CONGRESS}).order_by("-current_status_date")[0:100] # we have to limit to make this reasonably fast
    
    def make_feed_name(bill):
        return "bill:" + BillType.by_value(bill.bill_type).xml_code + str(bill.congress) + "-" + str(bill.number)
    return Feed.objects.filter(feedname__in=[make_feed_name(bill) for bill in bills if bill != None]) # batch load
Feed.register_feed(
    "billsearch:",
    title = lambda feed : bill_search_feed_title(feed.feedname.split(":", 1)[1]),
    link = lambda feed : "/congress/bills/browse?" + feed.feedname.split(":", 1)[1],
    includes = lambda feed : bill_search_feed_execute(feed.feedname.split(":", 1)[1]),
    meta = True,
    )

# Summaries
class BillSummary(models.Model):
    bill = models.OneToOneField(Bill, related_name="oursummary", on_delete=models.PROTECT)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    content = models.TextField(blank=True)
    
    def plain_text(self):
        import re
        content = re.sub("<br>|<li>", " \n ", self.content, re.I)
        
Example #51
0
 def AllVotesFeed():
     from events.models import Feed
     return Feed.get_noarg_feed("misc:allvotes")
Example #52
0
    @property
    def is_recently_added(self):
        return (self.created > (datetime.now() - timedelta(hours=36)))

    def abbrev_committee_name(self):
        return self.committee.sortname(True)

# feeds

from events.models import Feed, truncate_words
Feed.register_feed(
    "misc:allcommittee",
    title = "Committee Meetings",
    link = "/congress/committees",
    simple = True,
    sort_order = 103,
    category = "federal-committees",
    description = "Get an alert whenever a committee hearing or mark-up session is scheduled.",
    )
Feed.register_feed(
    "committee:",
    title = lambda feed : truncate_words(Committee.from_feed(feed).fullname, 12),
    noun = "committee",
    includes = lambda feed : [Committee.from_feed(feed).get_feed("bills"), Committee.from_feed(feed).get_feed("meetings")],
    link = lambda feed: Committee.from_feed(feed).get_absolute_url(),
    scoped_title = lambda feed : "All Events for This Committee",
    is_valid = lambda feed : Committee.from_feed(feed, test=True),
    category = "federal-committees",
    description = "You will get updates about major activity on bills referred to this commmittee plus notices of scheduled hearings and mark-up sessions.",
    )
Example #53
0
def person_details_user_view(request, pk):
    person = get_object_or_404(Person, pk=pk)
    return render_subscribe_inline(request, Feed.PersonFeed(person.id))
Example #54
0
    updated = models.DateTimeField(db_index=True, auto_now=True, help_text="The date the oversight topic's metadata/summary was last updated.")

    class Meta:
        ordering = ["-created"] # controls order on topic pages

    def summary_as_html(self):
        return markdown(self.summary)

    def summary_as_plain_text(self):
        # Make links nicer.
        return re.sub("\[(.*?)\]\(.*?\)", r"\1", self.summary)

from events.models import Feed
Feed.register_feed(
    "misc:oversight",
    title = "Congressional Oversight & Investigations",
    simple = True,
    slug = "oversight",
    intro_html = """<p>This feed includes all actions we are tracking on congressional oversight.</p>""",
    category = "oversight",
    description = "You will get updates when there are major congressional actions related to oversight of the executive branch.",
    )
Feed.register_feed(
    "oversight:",
    title = lambda feed : OversightTopic.from_feed(feed).title,
    noun = "oversight topic",
    link = lambda feed: OversightTopic.from_feed(feed).get_absolute_url(),
    category = "oversight",
    description = "You will get updates when there are major congressional actions related to this oversight topic.",
    )
Example #55
0
    def build_info():
        if re.match(r"\d", pk):
            person = get_object_or_404(Person, pk=pk)
        else:
            # support bioguide IDs for me
            person = get_object_or_404(Person, bioguideid=pk)

        # current role
        role = person.get_current_role()
        if role:
            active_role = True
        else:
            active_role = False
            try:
                role = person.roles.order_by('-enddate')[0]
            except IndexError:
                role = None

        # photo
        photo_url, photo_credit = person.get_photo()

        # analysis
        analysis_data = analysis.load_data(person)
        has_session_stats = False
        if role:
            try:
                has_session_stats = role.get_most_recent_session_stats()
            except:
                pass

        links = []
        if role.website:
            links.append(
                ("%s's Official Website" % person.lastname, role.website))
        if person.twitterid:
            links.append(("@" + person.twitterid,
                          "http://twitter.com/" + person.twitterid))
        if person.osid:
            links.append(
                ("OpenSecrets",
                 "http://www.opensecrets.org/politicians/summary.php?cid=" +
                 person.osid))
        if person.pvsid:
            links.append(("VoteSmart",
                          "http://votesmart.org/candidate/" + person.pvsid))
        if person.bioguideid:
            links.append(
                ("Bioguide",
                 "http://bioguide.congress.gov/scripts/biodisplay.pl?index=" +
                 person.bioguideid))
        if person.cspanid:
            links.append(
                ("C-SPAN",
                 "http://www.c-spanvideo.org/person/" + str(person.cspanid)))

        return {
            'person':
            person,
            'role':
            role,
            'active_role':
            active_role,
            'active_congressional_role':
            active_role
            and role.role_type in (RoleType.senator, RoleType.representative),
            'photo':
            photo_url,
            'photo_credit':
            photo_credit,
            'links':
            links,
            'analysis_data':
            analysis_data,
            'recent_bills':
            person.sponsored_bills.all().order_by('-introduced_date')[0:7],
            'committeeassignments':
            get_committee_assignments(person),
            'feed':
            Feed.PersonFeed(person.id),
            'cities':
            get_district_cities("%s-%02d" %
                                (role.state.lower(), role.district))
            if role and role.district else None,
            'has_session_stats':
            has_session_stats,
        }
Example #56
0
    def summary_as_html(self):
        return markdown(self.summary)

    def summary_as_plain_text(self):
        # Make links nicer.
        return re.sub("\[(.*?)\]\(.*?\)", r"\1", self.summary)


from events.models import Feed
Feed.register_feed(
    "misc:oversight",
    title="Congressional Oversight & Investigations",
    simple=True,
    slug="oversight",
    intro_html=
    """<p>This feed includes all actions we are tracking on congressional oversight.</p>""",
    category="oversight",
    description=
    "You will get updates when there are major congressional actions related to oversight of the executive branch.",
)
Feed.register_feed(
    "oversight:",
    title=lambda feed: OversightTopic.from_feed(feed).title,
    noun="oversight topic",
    link=lambda feed: OversightTopic.from_feed(feed).get_absolute_url(),
    category="oversight",
    description=
    "You will get updates when there are major congressional actions related to this oversight topic.",
)
Example #57
0
        return None

    def create_events(self):
        from events.models import Feed, Event
        with Event.update(self) as E:
            feeds = [Feed.from_name("misc:govtrackinsider")]
            E.add("post", self.published, feeds)

    def render_event(self, eventid, feeds):
        return {
            "type": "GovTrack Insider",
            "date": self.published,
            "date_has_no_time": False,
            "title": self.title,
            "url": self.get_absolute_url(),
            "body_text_template": """{{snippet|safe}}""",
            "body_html_template": """<p>{{snippet}}</p>""",
            "context": {
                "snippet": self.snippet,
                }
            }

Feed.register_feed(
    "misc:govtrackinsider",
    title = "GovTrack Insider Articles",
    simple = True,
    slug = "govtrack-insider",
    intro_html = """<p>This feed includes posts on <a href="https://medium.com/govtrack-insider">GovTrack Insider</a>.</p>""",
    description = "Get an update whenever we post a new article on GovTrack Insider.",
    )