It's been waaay too long since I last committed. Eesh.

This commit is contained in:
Dan Buch 2012-03-07 00:11:05 -05:00
parent a5b139f6e7
commit ee337ba7ee
15 changed files with 323 additions and 117 deletions

View File

@ -4,6 +4,7 @@ gem 'rails', '2.3.2'
gem 'active_presenter', '1.2.1' gem 'active_presenter', '1.2.1'
gem 'activesupport', '2.3.2' gem 'activesupport', '2.3.2'
gem 'awesome_print', '0.2.1', :require => 'ap' gem 'awesome_print', '0.2.1', :require => 'ap'
gem 'fastercsv'
gem 'haml' gem 'haml'
gem 'mc-settings' gem 'mc-settings'
gem 'mongrel', '1.1.5' gem 'mongrel', '1.1.5'
@ -11,6 +12,7 @@ gem 'nokogiri', '1.4.3.1'
gem 'rack', '1.2.1' gem 'rack', '1.2.1'
gem 'rake', '0.8.7' gem 'rake', '0.8.7'
gem 'rdoc' gem 'rdoc'
gem 'redis'
gem 'redis-session-store' gem 'redis-session-store'
gem 'responds_to_parent', '1.0.20091013' gem 'responds_to_parent', '1.0.20091013'
gem 'resque', '1.19.0' gem 'resque', '1.19.0'

View File

@ -31,6 +31,7 @@ GEM
fakeredis (0.2.2) fakeredis (0.2.2)
redis (~> 2.2.0) redis (~> 2.2.0)
fakeweb (1.3.0) fakeweb (1.3.0)
fastercsv (1.5.3)
fastthread (1.0.7) fastthread (1.0.7)
ffi (1.0.11) ffi (1.0.11)
foreman (0.40.0) foreman (0.40.0)
@ -168,6 +169,7 @@ DEPENDENCIES
fake_ftp (= 0.0.9) fake_ftp (= 0.0.9)
fakeredis (= 0.2.2) fakeredis (= 0.2.2)
fakeweb (= 1.3.0) fakeweb (= 1.3.0)
fastercsv
foreman foreman
guard guard
guard-livereload guard-livereload
@ -183,6 +185,7 @@ DEPENDENCIES
rake (= 0.8.7) rake (= 0.8.7)
rcov (= 0.9.9) rcov (= 0.9.9)
rdoc rdoc
redis
redis-session-store redis-session-store
remarkable_activerecord (= 3.1.13) remarkable_activerecord (= 3.1.13)
remarkable_rails (= 3.1.13) remarkable_rails (= 3.1.13)

View File

@ -1,44 +1,43 @@
class MashesController < ApplicationController class MashesController < ApplicationController
# GET /mashes
# GET /mashes.xml
def index def index
@mashes = Mash.all @mashes = Mash.all
respond_to do |format| respond_to do |format|
format.html # index.html.erb format.html
format.xml { render :xml => @mashes } format.xml { render :xml => @mashes }
end end
end end
# GET /mashes/1
# GET /mashes/1.xml
def show def show
@mash = Mash.find(params[:id]) @mash = Mash.find(params[:id])
respond_to do |format| respond_to do |format|
format.html # show.html.erb format.html
format.xml { render :xml => @mash } format.xml { render :xml => @mash }
end end
end end
# GET /mashes/new
# GET /mashes/new.xml
def new def new
@mash = Mash.new map_a, map_b = Map.rand(2)
@mash = Mash.new(
:requestor => request.remote_ip,
:map_a => map_a.id,
:map_b => map_b.id,
:winner => 0
)
respond_to do |format| respond_to do |format|
format.html # new.html.erb format.html
format.xml { render :xml => @mash } format.xml { render :xml => @mash }
end end
end end
# GET /mashes/1/edit
def edit def edit
@mash = Mash.find(params[:id]) @mash = Mash.find(params[:id])
end end
# POST /mashes
# POST /mashes.xml
def create def create
@mash = Mash.new(params[:mash]) @mash = Mash.new(params[:mash])
@ -54,8 +53,6 @@ class MashesController < ApplicationController
end end
end end
# PUT /mashes/1
# PUT /mashes/1.xml
def update def update
@mash = Mash.find(params[:id]) @mash = Mash.find(params[:id])
@ -71,8 +68,6 @@ class MashesController < ApplicationController
end end
end end
# DELETE /mashes/1
# DELETE /mashes/1.xml
def destroy def destroy
@mash = Mash.find(params[:id]) @mash = Mash.find(params[:id])
@mash.destroy @mash.destroy

View File

@ -1,5 +1,25 @@
require 'fastercsv'
class Map < ActiveRecord::Base class Map < ActiveRecord::Base
def self.from_city_name(city_name) def self.from_city_name(city_name)
self.find_or_initialize_by_name(city_name).save! self.find_or_initialize_by_name(city_name).save!
end end
def self.rand(count = 2)
self.find(:all, :order => 'RANDOM()', :limit => count)
end
def self.import(csv_filename)
FasterCSV.parse(open(csv_filename), :headers => true,
:header_converters => [:downcase, :symbol]).each do |row|
map = self.find_or_initialize_by_name(
"#{row[:city]}, #{row[:country]}"
)
map.save
if block_given?
yield map
end
end
end
end end

View File

@ -2,5 +2,5 @@ require 'mc-settings'
Setting.load( Setting.load(
:path => Rails.root, :path => Rails.root,
:files => ['config/settings/default.yml'] :files => ['config/settings.yml']
) )

View File

@ -0,0 +1,5 @@
resque_web:
port: 15678
redis:
port: 16379

View File

@ -1,8 +0,0 @@
resque_web:
port: 15678
redis:
port: 16379
map:
base_url: 'http://en.wikipedia.org/wiki/List_of_towns_and_cities_with_100,000_or_more_inhabitants/cityname:_{FIRST_LETTER}'

View File

@ -0,0 +1,191 @@
country,city
Afghanistan,Kabul
Albania,Tirane
Algeria,Algiers
Andorra,Andorra la Vella
Angola,Luanda
Antigua and Barbuda,St. John's
Argentina,Buenos Aires
Australia,Canberra
Austria,Vienna
Azerbaijan,Baku
Bahamas,Nassau
Bahrain,Manama
Bangladesh,Dhaka
Barbados,Bridgetown
Belarus,Minsk
Belgium,Brussels
Belize,Belmopan
Benin,Porto-Novo
Bhutan,Thimphu
Bolivia,Sucre
Bosnia and Herzegovina,Sarajevo
Botswana,Gaborone
Brazil,Brasilia
Brunei,Darussalam Bandar Seri Begawan
Bulgaria,Sofia
Burkina Faso,Ouagadougou
Burundi,Bujumbura
Cambodia,Phnom Penh
Cameroon,Yaounde
Canada,Ottawa
Cape Verde,Praia
Central African Republic,Bangui
Chad,N'Djamena
Chile,Santiago
China,Beijing
Colombia,Bogota
Comoros,Moroni
Congo,Brazzaville
Congo,Kinshasa
Costa Rica,San Jose
Cote d'Ivoire,Yamoussoukro
Croatia,Zagreb
Cuba,Havana
Cyprus,Nicosia
Czech Republic,Prague
Denmark,Copenhagen
Djibouti,Djibouti
Dominica,Roseau
Dominican Republic,Santo Domingo
Ecuador,Quito
Egypt,Cairo
El Salvador,San Salvador
Equatorial Guinea,Malabo
Eritrea,Asmara
Estonia,Tallinn
Ethiopia,Addis Ababa
Fiji,Suva
Finland,Helsinki
France,Paris
Gabon,Libreville
Gambia,Banjul
Georgia,Tbilisi
Germany,Berlin
Ghana,Accra
Greece,Athens
Grenada,St. George's
Guatemala,Guatemala City
Guinea,Conakry
Guinea-Bissau,Bissau
Guyana,Georgetown
Haiti,Port-au-Prince
Honduras,Tegucigalpa
Hungary,Budapest
Iceland,Reykjavik
India,New Delhi
Indonesia,Jakarta
Iran,Teheran
Iraq,Baghdad
Ireland,Dublin
Israel,Jerusalem
Italy,Rome
Jamaica,Kingston
Japan,Tokyo
Jordan,Amman
Kazakhstan,Astana
Kenya,Nairobi
Kiribati,South Tarawa
Korea,Pyongyang
Korea,Seoul
Kuwait,Kuwait City
Kyrgyzstan,Bishkek
Laos,Vientiane
Latvia,Riga
Lebanon,Beirut
Lesotho,Maseru
Liberia,Monrovia
Libya,Tripoli
Liechtenstein,Vaduz
Lithuania,Vilnius
Luxembourg,Luxembourg
Macedonia,Skopje
Madagascar,Antananarivo
Malawi,Lilongwe
Malaysia,Kuala Lumpur
Maldives,Male
Mali,Bamako
Malta,Valletta
Marshall Islands,Majuro
Mauritania,Nouakchott
Mauritius,Port Louis
Mexico,Mexico City
Micronesia,Palikir
Moldova,Chisinau
Monaco,Monaco
Mongolia,Ulan Bator
Morocco,Rabat
Mozambique,Maputo
Myanmar,Rangoon
Namibia,Windhoek
Nauru,Yaren
Nepal,Kathmandu
Netherlands,Amsterdam
New Zealand,Wellington
Nicaragua,Managua
Niger,Niamey
Nigeria,Abuja
Norway,Oslo
Oman,Muscat
Pakistan,Islamabad
Palau,Koror
Panama,Panama City
Papua New Guinea,Port Moresby
Paraguay,Asuncion
Peru,Lima
Philippines,Manila
Poland,Warsaw
Portugal,Lisbon
Qatar,Doha
Romania,Bucharest
Russian Federation,Moscow
Rwanda,Kigali
St. Kitts and Nevis,Basseterre
St. Lucia,Castries
St. Vincent and The Grenadines,Kingstown
Samoa,Apia
San Marino,San Marino
Sao Tome and Principe,Sao Tome
Saudi Arabia,Riyadh
Senegal,Dakar
Seychelles,Victoria
Sierra Leone,Freetown
Singapore,Singapore
Slovakia,Bratislava
Slovenia,Ljubljana
Solomon Islands,Honiara
Somalia,Mogadishu
South Africa,Pretoria
Spain,Madrid
Sri Lanka,Colombo
Sudan,Khartoum
Suriname,Paramaribo
Swaziland,Mbabane
Sweden,Stockholm
Switzerland,Bern
Syria,Damascus
Taiwan,Taipei
Tajikistan,Dushanbe
Tanzania,Dar es Salaam
Thailand,Bangkok
Togo,Lome
Tonga,Nuku'alofa
Trinidad and Tobago,Port-of-Spain
Tunisia,Tunis
Turkey,Ankara
Turkmenistan,Ashgabat
Tuvalu,Funafuti
Uganda,Kampala
Ukraine,Kiev
United Arab Emirates,Abu Dhabi
United Kingdom,London
United States,Washington
Uruguay,Montevideo
Uzbekistan,Tashkent
Vanuatu,Port Vila
Venezuela,Caracas
Vietnam,Hanoi
Western Sahara,El Aaiun
Yemen,Sana
Zambia,Lusaka
Zimbabwe,Harare
1 country city
2 Afghanistan Kabul
3 Albania Tirane
4 Algeria Algiers
5 Andorra Andorra la Vella
6 Angola Luanda
7 Antigua and Barbuda St. John's
8 Argentina Buenos Aires
9 Australia Canberra
10 Austria Vienna
11 Azerbaijan Baku
12 Bahamas Nassau
13 Bahrain Manama
14 Bangladesh Dhaka
15 Barbados Bridgetown
16 Belarus Minsk
17 Belgium Brussels
18 Belize Belmopan
19 Benin Porto-Novo
20 Bhutan Thimphu
21 Bolivia Sucre
22 Bosnia and Herzegovina Sarajevo
23 Botswana Gaborone
24 Brazil Brasilia
25 Brunei Darussalam Bandar Seri Begawan
26 Bulgaria Sofia
27 Burkina Faso Ouagadougou
28 Burundi Bujumbura
29 Cambodia Phnom Penh
30 Cameroon Yaounde
31 Canada Ottawa
32 Cape Verde Praia
33 Central African Republic Bangui
34 Chad N'Djamena
35 Chile Santiago
36 China Beijing
37 Colombia Bogota
38 Comoros Moroni
39 Congo Brazzaville
40 Congo Kinshasa
41 Costa Rica San Jose
42 Cote d'Ivoire Yamoussoukro
43 Croatia Zagreb
44 Cuba Havana
45 Cyprus Nicosia
46 Czech Republic Prague
47 Denmark Copenhagen
48 Djibouti Djibouti
49 Dominica Roseau
50 Dominican Republic Santo Domingo
51 Ecuador Quito
52 Egypt Cairo
53 El Salvador San Salvador
54 Equatorial Guinea Malabo
55 Eritrea Asmara
56 Estonia Tallinn
57 Ethiopia Addis Ababa
58 Fiji Suva
59 Finland Helsinki
60 France Paris
61 Gabon Libreville
62 Gambia Banjul
63 Georgia Tbilisi
64 Germany Berlin
65 Ghana Accra
66 Greece Athens
67 Grenada St. George's
68 Guatemala Guatemala City
69 Guinea Conakry
70 Guinea-Bissau Bissau
71 Guyana Georgetown
72 Haiti Port-au-Prince
73 Honduras Tegucigalpa
74 Hungary Budapest
75 Iceland Reykjavik
76 India New Delhi
77 Indonesia Jakarta
78 Iran Teheran
79 Iraq Baghdad
80 Ireland Dublin
81 Israel Jerusalem
82 Italy Rome
83 Jamaica Kingston
84 Japan Tokyo
85 Jordan Amman
86 Kazakhstan Astana
87 Kenya Nairobi
88 Kiribati South Tarawa
89 Korea Pyongyang
90 Korea Seoul
91 Kuwait Kuwait City
92 Kyrgyzstan Bishkek
93 Laos Vientiane
94 Latvia Riga
95 Lebanon Beirut
96 Lesotho Maseru
97 Liberia Monrovia
98 Libya Tripoli
99 Liechtenstein Vaduz
100 Lithuania Vilnius
101 Luxembourg Luxembourg
102 Macedonia Skopje
103 Madagascar Antananarivo
104 Malawi Lilongwe
105 Malaysia Kuala Lumpur
106 Maldives Male
107 Mali Bamako
108 Malta Valletta
109 Marshall Islands Majuro
110 Mauritania Nouakchott
111 Mauritius Port Louis
112 Mexico Mexico City
113 Micronesia Palikir
114 Moldova Chisinau
115 Monaco Monaco
116 Mongolia Ulan Bator
117 Morocco Rabat
118 Mozambique Maputo
119 Myanmar Rangoon
120 Namibia Windhoek
121 Nauru Yaren
122 Nepal Kathmandu
123 Netherlands Amsterdam
124 New Zealand Wellington
125 Nicaragua Managua
126 Niger Niamey
127 Nigeria Abuja
128 Norway Oslo
129 Oman Muscat
130 Pakistan Islamabad
131 Palau Koror
132 Panama Panama City
133 Papua New Guinea Port Moresby
134 Paraguay Asuncion
135 Peru Lima
136 Philippines Manila
137 Poland Warsaw
138 Portugal Lisbon
139 Qatar Doha
140 Romania Bucharest
141 Russian Federation Moscow
142 Rwanda Kigali
143 St. Kitts and Nevis Basseterre
144 St. Lucia Castries
145 St. Vincent and The Grenadines Kingstown
146 Samoa Apia
147 San Marino San Marino
148 Sao Tome and Principe Sao Tome
149 Saudi Arabia Riyadh
150 Senegal Dakar
151 Seychelles Victoria
152 Sierra Leone Freetown
153 Singapore Singapore
154 Slovakia Bratislava
155 Slovenia Ljubljana
156 Solomon Islands Honiara
157 Somalia Mogadishu
158 South Africa Pretoria
159 Spain Madrid
160 Sri Lanka Colombo
161 Sudan Khartoum
162 Suriname Paramaribo
163 Swaziland Mbabane
164 Sweden Stockholm
165 Switzerland Bern
166 Syria Damascus
167 Taiwan Taipei
168 Tajikistan Dushanbe
169 Tanzania Dar es Salaam
170 Thailand Bangkok
171 Togo Lome
172 Tonga Nuku'alofa
173 Trinidad and Tobago Port-of-Spain
174 Tunisia Tunis
175 Turkey Ankara
176 Turkmenistan Ashgabat
177 Tuvalu Funafuti
178 Uganda Kampala
179 Ukraine Kiev
180 United Arab Emirates Abu Dhabi
181 United Kingdom London
182 United States Washington
183 Uruguay Montevideo
184 Uzbekistan Tashkent
185 Vanuatu Port Vila
186 Venezuela Caracas
187 Vietnam Hanoi
188 Western Sahara El Aaiun
189 Yemen Sana
190 Zambia Lusaka
191 Zimbabwe Harare

View File

@ -1,8 +1,7 @@
class CreateMaps < ActiveRecord::Migration class CreateMaps < ActiveRecord::Migration
def self.up def self.up
create_table :maps do |t| create_table :maps do |t|
t.string :name t.string :name, :null => false
t.string :unique_hash
t.timestamps t.timestamps
end end

View File

@ -1,10 +1,10 @@
class CreateMashes < ActiveRecord::Migration class CreateMashes < ActiveRecord::Migration
def self.up def self.up
create_table :mashes do |t| create_table :mashes do |t|
t.string :requester t.string :requester, :null => false
t.integer :map_a t.integer :map_a, :null => false
t.integer :map_b t.integer :map_b, :null => false
t.integer :winner t.integer :winner, :null => false
t.timestamps t.timestamps
end end

View File

@ -12,17 +12,16 @@
ActiveRecord::Schema.define(:version => 20120304164625) do ActiveRecord::Schema.define(:version => 20120304164625) do
create_table "maps", :force => true do |t| create_table "maps", :force => true do |t|
t.string "name" t.string "name", :null => false
t.string "unique_hash"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end
create_table "mashes", :force => true do |t| create_table "mashes", :force => true do |t|
t.string "requester" t.string "requester", :null => false
t.integer "map_a" t.integer "map_a", :null => false
t.integer "map_b" t.integer "map_b", :null => false
t.integer "winner" t.integer "winner", :null => false
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end

View File

@ -0,0 +1,61 @@
require 'base64'
require 'logger'
require 'uri'
require 'nokogiri'
require 'typhoeus'
class GoogleMapLocationFetcher
attr_accessor :base_map_url, :log
def initialize
@base_map_url = [
'http://maps.googleapis.com/maps/api/staticmap',
'?zoom=15',
'&sensor=false',
'&size=512x512',
'&maptype=satellite',
].join('')
@log = Logger.new(
File.expand_path('../log/map-crawler.log', File.dirname(__FILE__))
)
@log.level = Logger::INFO
@log.formatter = lambda do |severity, time, prog, message|
"#{time} - #{severity} - #{message}\n"
end
end
def self.mapdump_callback(location, image)
puts "Map '#{location}':"
puts Base64.encode64(image)
end
def fetch(locations, &callback)
callback ||= self.class.method(:mapdump_callback)
hydra = Typhoeus::Hydra.new(:initial_pool_size => 26)
locations.each do |location|
request = Typhoeus::Request.new(
"#{@base_map_url}&center=#{URI.encode(location)}"
)
request.on_complete do |response|
handle_response(response, location, &callback)
end
hydra.queue(request)
end
hydra.run
end
def handle_response(response, location, &callback)
@log.info("Handling request at url #{response.effective_url}")
if response.success? and response.headers_hash[:content_type] =~ /image\/.*/
callback.call(location, response.body)
else
callback.call(location, '')
end
end
end

View File

@ -1,49 +0,0 @@
require 'logger'
require 'nokogiri'
require 'typhoeus'
class MapCrawler
attr_accessor :base_map_url, :log, :request_pool
def initialize(base_map_url)
@base_map_url = base_map_url
@log = Logger.new(
File.expand_path('../log/map-crawler.log', File.dirname(__FILE__))
)
@log.level = Logger::INFO
@log.formatter = lambda do |severity, time, prog, message|
"#{time} - #{severity} - #{message}\n"
end
end
def crawl(city_name_callback = nil)
city_name_callback ||= lambda { |n| puts n }
hydra = Typhoeus::Hydra.new(:initial_pool_size => 26)
('A'..'Z').each do |letter|
letter_request = Typhoeus::Request.new(
@base_map_url.gsub(/\{FIRST_LETTER\}/, letter)
)
letter_request.on_complete do |response|
handle_cities(response, city_name_callback)
end
hydra.queue(letter_request)
end
hydra.run
end
def handle_cities(response, city_name_callback)
@log.info("Handling cities at url #{response.effective_url}")
doc = Nokogiri::HTML(response.body)
doc.css('div.mw-content-ltr ul')[3].css('li a').each do |anchor|
@log.info("Found city: #{anchor.text}")
city_name_callback.call(anchor.text.strip)
end
end
end

View File

@ -1,6 +1,13 @@
namespace :maps do namespace :maps do
desc 'Index the maps!' desc 'Seed the maps!'
task :index => :environment do task :seed => :environment do
MapCrawler.new(Setting.map(:base_url)).crawl(Map.method(:from_city_name)) require 'app/models/map'
csv_filename = File.expand_path(
'../../db/capital-cities.csv', File.dirname(__FILE__)
)
Map.import(csv_filename) do |map|
puts "Seeded map '#{map.name}'"
end
end end
end end

View File

@ -1,19 +0,0 @@
require 'spec_helper'
describe MapCrawler do
let(:subject) { MapCrawler.new(Setting.map(:base_url)) }
describe 'when crawling for actual maps', :integration => true do
it 'should increment the map count for each map found' do
map_count = 0
count_increment = lambda do |n|
map_count += 1
end
expect do
subject.crawl(count_increment)
end.to change{ map_count }.by_at_least(26)
end
end
end