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)
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)
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
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), }
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 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), }
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
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), }
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)
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")
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")])
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 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), }
def get_subject_title(self): return Feed.from_name(self.subject).title
def get_subject_link(self): return Feed.from_name(self.subject).link
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())