Skip to content
Browse files

With working politician lookup and caching ... onto the javascript

  • Loading branch information...
1 parent 7c088f3 commit 03752a9994bd51061c77b1572eec902b722d2cb1 @jashkenas committed Jan 20, 2009
View
9 app/controllers/congressional_controller.rb
@@ -0,0 +1,9 @@
+class CongressionalController < ApplicationController
+
+ def find
+ first_name, last_name = params[:name].split('_')
+ pol = Politician.find_or_create_by_first_name_and_last_name(first_name, last_name)
+ render :text => pol.information
+ end
+
+end
View
24 app/models/politician.rb
@@ -0,0 +1,24 @@
+class Politician < ActiveRecord::Base
+
+ validates_presence_of :first_name, :last_name
+
+ # Return cached data or find it out.
+ def information
+ gather_information if stale?
+ self.json
+ end
+
+
+ # Go out and re-spider this politician.
+ def gather_information
+ self.json = Sleuth.new.dig_up_dirt(first_name, last_name).to_json
+ save
+ end
+
+
+ # Is our cache empty or past its expiration date?
+ def stale?
+ updated_at < 1.week.ago || json == '{}'
+ end
+
+end
View
2 config/routes.rb
@@ -34,6 +34,8 @@
# map.root :controller => "welcome"
# See how all your routes lay out with "rake routes"
+
+ map.search 'find/:name', :controller => 'congressional', :action => 'find'
# Install the default routes as the lowest priority.
map.connect ':controller/:action/:id'
View
16 db/migrate/20090121025708_create_politicians.rb
@@ -0,0 +1,16 @@
+class CreatePoliticians < ActiveRecord::Migration
+ def self.up
+ create_table :politicians do |t|
+ t.string 'first_name', :null => false
+ t.string 'last_name', :null => false
+ t.text 'json', :null => false, :default => '{}'
+ t.timestamps
+ end
+
+ add_index :politicians, ['first_name', 'last_name']
+ end
+
+ def self.down
+ drop_table :politicians
+ end
+end
View
24 db/schema.rb
@@ -0,0 +1,24 @@
+# This file is auto-generated from the current state of the database. Instead of editing this file,
+# please use the migrations feature of Active Record to incrementally modify your database, and
+# then regenerate this schema definition.
+#
+# Note that this schema.rb definition is the authoritative source for your database schema. If you need
+# to create the application database on another system, you should be using db:schema:load, not running
+# all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
+# you'll amass, the slower it'll run and the greater likelihood for issues).
+#
+# It's strongly recommended to check this file into your version control system.
+
+ActiveRecord::Schema.define(:version => 20090121025708) do
+
+ create_table "politicians", :force => true do |t|
+ t.string "first_name", :null => false
+ t.string "last_name", :null => false
+ t.text "json", :default => "{}", :null => false
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "politicians", ["first_name", "last_name"], :name => "index_politicians_on_first_name_and_last_name"
+
+end
View
8 lib/sleuth.rb
@@ -7,6 +7,7 @@ class Sleuth
WATCHDOG = 'http://watchdog.net'
SUNLIGHT = 'http://services.sunlightlabs.com/api'
+ NYTIMES = 'http://api.nytimes.com/svc/politics/v2/us/legislative/congress'
# Dig up all the dirt available about a congressman...
@@ -44,6 +45,13 @@ def search_watchdog(first_name, last_name)
end
end
+ # Dig up dirt from the Gray Lady...
+ def search_nytimes(first_name, last_name)
+ # NYTimes API doesn't seem to return much useful congressional data,
+ # nor does it allow you to search by name.
+ # Maybe implement this later.
+ end
+
private
View
286 public/index.html
@@ -1,278 +1,10 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
- <head>
- <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
- <title>Ruby on Rails: Welcome aboard</title>
- <style type="text/css" media="screen">
- body {
- margin: 0;
- margin-bottom: 25px;
- padding: 0;
- background-color: #f0f0f0;
- font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana";
- font-size: 13px;
- color: #333;
- }
-
- h1 {
- font-size: 28px;
- color: #000;
- }
-
- a {color: #03c}
- a:hover {
- background-color: #03c;
- color: white;
- text-decoration: none;
- }
-
-
- #page {
- background-color: #f0f0f0;
- width: 750px;
- margin: 0;
- margin-left: auto;
- margin-right: auto;
- }
-
- #content {
- float: left;
- background-color: white;
- border: 3px solid #aaa;
- border-top: none;
- padding: 25px;
- width: 500px;
- }
-
- #sidebar {
- float: right;
- width: 175px;
- }
-
- #footer {
- clear: both;
- }
-
-
- #header, #about, #getting-started {
- padding-left: 75px;
- padding-right: 30px;
- }
-
-
- #header {
- background-image: url("images/rails.png");
- background-repeat: no-repeat;
- background-position: top left;
- height: 64px;
- }
- #header h1, #header h2 {margin: 0}
- #header h2 {
- color: #888;
- font-weight: normal;
- font-size: 16px;
- }
-
-
- #about h3 {
- margin: 0;
- margin-bottom: 10px;
- font-size: 14px;
- }
-
- #about-content {
- background-color: #ffd;
- border: 1px solid #fc0;
- margin-left: -11px;
- }
- #about-content table {
- margin-top: 10px;
- margin-bottom: 10px;
- font-size: 11px;
- border-collapse: collapse;
- }
- #about-content td {
- padding: 10px;
- padding-top: 3px;
- padding-bottom: 3px;
- }
- #about-content td.name {color: #555}
- #about-content td.value {color: #000}
-
- #about-content.failure {
- background-color: #fcc;
- border: 1px solid #f00;
- }
- #about-content.failure p {
- margin: 0;
- padding: 10px;
- }
-
-
- #getting-started {
- border-top: 1px solid #ccc;
- margin-top: 25px;
- padding-top: 15px;
- }
- #getting-started h1 {
- margin: 0;
- font-size: 20px;
- }
- #getting-started h2 {
- margin: 0;
- font-size: 14px;
- font-weight: normal;
- color: #333;
- margin-bottom: 25px;
- }
- #getting-started ol {
- margin-left: 0;
- padding-left: 0;
- }
- #getting-started li {
- font-size: 18px;
- color: #888;
- margin-bottom: 25px;
- }
- #instructions h2 {
- margin: 0;
- font-weight: bold;
- font-size: 18px;
- color: #333;
- }
- #instructions p {
- color: #555;
- font-size: 13px;
- }
- #instructions pre {
- background: black;
- color: #ccc;
- padding: 0.3em 0.5em;
- font-size: 90%;
- }
-
-
- #search {
- margin: 0;
- padding-top: 10px;
- padding-bottom: 10px;
- font-size: 11px;
- }
- #search input {
- font-size: 11px;
- margin: 2px;
- }
- #search-text {width: 170px}
-
-
- #sidebar ul {
- margin-left: 0;
- padding-left: 0;
- }
- #sidebar ul h3 {
- margin-top: 25px;
- font-size: 16px;
- padding-bottom: 10px;
- border-bottom: 1px solid #ccc;
- }
- #sidebar li {
- list-style-type: none;
- }
- #sidebar ul.links li {
- margin-bottom: 5px;
- }
-
- </style>
- <script type="text/javascript" src="javascripts/prototype.js"></script>
- <script type="text/javascript" src="javascripts/effects.js"></script>
- <script type="text/javascript">
- window.onload = function() {
- $('search-text').value = '';
- $('search').onsubmit = function() {
- $('search-text').value = 'site:rubyonrails.org ' + $F('search-text');
- }
- }
- </script>
- </head>
- <body>
- <div id="page">
- <div id="sidebar">
- <ul id="sidebar-items">
- <li>
- <form id="search" action="http://www.google.com/search" method="get">
- <input type="hidden" name="hl" value="en" />
- <input type="text" id="search-text" name="q" value="site:rubyonrails.org " />
- <input type="submit" value="Search" /> the Rails site
- </form>
- </li>
-
- <li>
- <h3>Join the community</h3>
- <ul class="links">
- <li><a href="http://www.rubyonrails.org/">Ruby on Rails</a></li>
- <li><a href="http://weblog.rubyonrails.org/">Official weblog</a></li>
- <li><a href="http://lists.rubyonrails.org/">Mailing lists</a></li>
- <li><a href="http://wiki.rubyonrails.org/rails/pages/IRC">IRC channel</a></li>
- <li><a href="http://wiki.rubyonrails.org/">Wiki</a></li>
- <li><a href="http://dev.rubyonrails.org/">Bug tracker</a></li>
- </ul>
- </li>
-
- <li>
- <h3>Browse the documentation</h3>
- <ul class="links">
- <li><a href="http://api.rubyonrails.org/">Rails API</a></li>
- <li><a href="http://heroku.com/docs/api/">Heroku API</a></li>
- <li><a href="http://stdlib.rubyonrails.org/">Ruby standard library</a></li>
- <li><a href="http://corelib.rubyonrails.org/">Ruby core</a></li>
- </ul>
- </li>
- </ul>
- </div>
-
- <div id="content">
- <div id="header">
- <h1>Welcome aboard</h1>
- <h2>You&rsquo;re riding the Rails!</h2>
- </div>
-
- <div id="getting-started">
- <h1>Getting started</h1>
- <h2>Here&rsquo;s how to get rolling:</h2>
-
- <div id="instructions">
- <h2>Use the online editor</h2>
- <p><a id="edit_link" href="#">Edit your app</a> online</h2>, or <a id="import_link" href="#">import a tarball</a>.</p>
- </div>
-
- <div id="instructions">
- <h2>Work locally and deploy to Heroku</h2>
- <pre>gem install heroku
-heroku clone <span id="app_name1">yourapp</span>
-cd <span id="app_name2">yourapp</span>
-[..local edits..]
-git add .
-git commit -m "local changes"
-git push</pre>
- </div>
- </div>
- </div>
-
- <div id="footer">&nbsp;</div>
- </div>
-
-<script type="text/javascript">
- var parts = location.hostname.split('.')
- var app_name = parts[0]
- var domain = parts.slice(1).join('.')
-
- document.getElementById('app_name1').innerHTML = app_name
- document.getElementById('app_name2').innerHTML = app_name
- document.getElementById('edit_link').href = 'http://edit.' + location.hostname
- document.getElementById('import_link').href = 'http://' + domain + '/myapps/' + app_name + '/import_export'
-</script>
-
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Know Thy Congressman</title>
+</head>
+<body>
+ <h1>Know Thy Congressman</h1>
</body>
-
-</html>
+</html>
View
7 test/fixtures/politicians.yml
@@ -0,0 +1,7 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+
+# one:
+# column: value
+#
+# two:
+# column: value
View
8 test/unit/politician_test.rb
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class PoliticianTest < ActiveSupport::TestCase
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end

0 comments on commit 03752a9

Please sign in to comment.
Something went wrong with that request. Please try again.