@@ -0,0 +1,4 @@ | |||||
*.sqlite | |||||
*.zip | |||||
.ruby-* | |||||
_site |
@@ -0,0 +1,6 @@ | |||||
source 'https://rubygems.org' | |||||
ruby '2.3.1' | |||||
gem 'scraperwiki', :git => 'https://github.com/openaustralia/scraperwiki-ruby/', :branch => 'morph_defaults' | |||||
gem 'haml' |
@@ -0,0 +1,34 @@ | |||||
GIT | |||||
remote: https://github.com/openaustralia/scraperwiki-ruby/ | |||||
revision: fc50176812505e463077d5c673d504a6a234aa78 | |||||
branch: morph_defaults | |||||
specs: | |||||
scraperwiki (3.0.1) | |||||
httpclient | |||||
sqlite_magic | |||||
GEM | |||||
remote: https://rubygems.org/ | |||||
specs: | |||||
haml (5.0.4) | |||||
temple (>= 0.8.0) | |||||
tilt | |||||
httpclient (2.8.3) | |||||
sqlite3 (1.3.13) | |||||
sqlite_magic (0.0.6) | |||||
sqlite3 | |||||
temple (0.8.0) | |||||
tilt (2.0.8) | |||||
PLATFORMS | |||||
ruby | |||||
DEPENDENCIES | |||||
haml | |||||
scraperwiki! | |||||
RUBY VERSION | |||||
ruby 2.3.1p112 | |||||
BUNDLED WITH | |||||
1.16.5 |
@@ -0,0 +1,69 @@ | |||||
#!/usr/bin/env ruby | |||||
require 'scraperwiki' | |||||
require 'haml' | |||||
require 'pp' | |||||
require 'logger' | |||||
require_relative '../lib/helpers' | |||||
OUTPUT_DIR = '_site' | |||||
VIEWS_DIR = File.join('views') | |||||
LAYOUT_FN = File.join(VIEWS_DIR, 'layout.haml') | |||||
def write_page(path_items, template, locals = {}) | |||||
dir = File.join(OUTPUT_DIR, path_items) | |||||
FileUtils.mkdir_p(dir) | |||||
@log.debug dir | |||||
fn = File.join(dir, 'index.html') | |||||
# https://stackoverflow.com/questions/6125265/using-layouts-in-haml-files-independently-of-rails | |||||
html = Haml::Engine.new(File.read(LAYOUT_FN)).render do | |||||
Haml::Engine.new(File.read(File.join(VIEWS_DIR, "#{template}.haml"))).render(Object.new, locals) | |||||
end | |||||
File.write(fn, html) | |||||
@log.info fn | |||||
@pages += 1 | |||||
# TODO - add page to sitemap.xml or sitemap.txt | |||||
# https://support.google.com/webmasters/answer/183668?hl=en&ref_topic=4581190 | |||||
end | |||||
def create_output_dir | |||||
# Recursively delete working directory to ensure no redundant files are left behind from previous builds. | |||||
# FileUtils.rm_rf(@working_dir) | |||||
Dir.mkdir(@working_dir) unless File.directory?(@working_dir) | |||||
# Dir.chdir(@working_dir) | |||||
# Copy `public` dir to output dir | |||||
FileUtils.copy_entry('public', @working_dir) | |||||
end | |||||
def gen_homepage | |||||
decisions = ScraperWiki.select("* from `applications` order by date_decision desc limit 20") | |||||
write_page('.', 'index', { decisions: decisions }) | |||||
end | |||||
def gen_authorities | |||||
auths = ScraperWiki.select("distinct(authority_name) as authority_name from applications order by authority_name") | |||||
write_page('authorities', 'authorities', { auths: auths }) | |||||
auths.each do |auth| | |||||
summary = ScraperWiki.select(" | |||||
status, decision, appeal_status, appeal_decision, count(*) as qty | |||||
from applications | |||||
where authority_name = '#{auth['authority_name']}' | |||||
group by status, decision, appeal_status, appeal_decision | |||||
") | |||||
apps = ScraperWiki.select("* from applications where authority_name='#{auth['authority_name']}' order by date_received") | |||||
write_page(['authorities', slug(auth['authority_name'])], 'authority', { apps: apps, auth: auth, summary: summary }) | |||||
end | |||||
end | |||||
@working_dir = File.join(Dir.pwd, OUTPUT_DIR) | |||||
puts @working_dir | |||||
# exit | |||||
@log = Logger.new($stdout) | |||||
@pages = 0 | |||||
create_output_dir | |||||
gen_homepage | |||||
gen_authorities |
@@ -0,0 +1,17 @@ | |||||
def short_date(s) | |||||
return if s.nil? | |||||
Date.parse(s).strftime("%e %b %Y").gsub(' ', ' ') | |||||
end | |||||
def cleanup(s) | |||||
return if s.nil? | |||||
s.sub!('Unknown', '') | |||||
s.sub!('Not Available', '') | |||||
# s = "<span class=grant>#{s}</span>" if s.match(/approve/i) | |||||
# s = "<span class=refuse>#{s}</span>" if s.match(/refuse/i) | |||||
s | |||||
end | |||||
def slug(s) | |||||
s.downcase.gsub(' ', '-') | |||||
end |
@@ -0,0 +1,192 @@ | |||||
body | |||||
{ | |||||
background-color: #fff; | |||||
color: #555; | |||||
font-family: Helvetica, Arial, sans-serif; | |||||
font-size: 100%; | |||||
width: 100%; | |||||
line-height: 1.5em; | |||||
margin: 0; | |||||
padding: 0; | |||||
} | |||||
.warning { | |||||
padding: 10px 15px; | |||||
background-color: #fcfcfc; | |||||
margin: 25px 0; | |||||
} | |||||
p | |||||
{ | |||||
font-size: 110%; | |||||
} | |||||
#main | |||||
{ | |||||
width: 920px; | |||||
margin: 50px auto; | |||||
} | |||||
tr.footer { | |||||
border-top: 1px solid #eee; | |||||
border-bottom: 0px solid black; | |||||
} | |||||
tr.header { | |||||
border-bottom: 1px solid #eee; | |||||
} | |||||
#header | |||||
{ | |||||
font-size: 100%; | |||||
/* background-color: #e8f3f4; */ | |||||
color: #999; | |||||
text-align: left; | |||||
margin: 0 0 0px 0; | |||||
height: 100%; | |||||
} | |||||
#header_inner { | |||||
margin: 0 auto; | |||||
padding: 10px 0; | |||||
width: 930px; | |||||
} | |||||
#header h1 { | |||||
font-size: 180%; | |||||
color: #555; | |||||
} | |||||
.grant { | |||||
color: green; | |||||
} | |||||
.refuse { | |||||
color: red; | |||||
} | |||||
a | |||||
{ | |||||
padding: 1px 4px; | |||||
color: #999; | |||||
text-decoration: none; | |||||
} | |||||
a:visited | |||||
{ | |||||
padding: 1px 4px; | |||||
color: #111; | |||||
text-decoration: none; | |||||
} | |||||
a:hover | |||||
{ | |||||
background-color: #4f4f4f; | |||||
color: #fff; | |||||
} | |||||
h1 | |||||
{ | |||||
margin: 40px 0; | |||||
line-height: 1.4em; | |||||
font-weight: bold; | |||||
color: #555; | |||||
} | |||||
h2 | |||||
{ | |||||
margin: 20px 0 0 0; | |||||
line-height: 1.5em; | |||||
font-weight: bold; | |||||
color: #555; | |||||
} | |||||
h3 | |||||
{ | |||||
margin: 30px 0 0 0; | |||||
line-height: 1.5em; | |||||
font-weight: bold; | |||||
color: #555; | |||||
} | |||||
.highlight | |||||
{ | |||||
background-color: #e8f3f4; | |||||
} | |||||
strong | |||||
{ | |||||
color: #000; | |||||
} | |||||
table | |||||
{ | |||||
border-collapse: collapse; | |||||
margin: 20px 0 60px 0; | |||||
} | |||||
td, th | |||||
{ | |||||
padding: 6px; | |||||
} | |||||
th { | |||||
font-weight: bold; | |||||
text-align: left; | |||||
} | |||||
tr | |||||
{ | |||||
border-bottom: 1px solid #eee; | |||||
} | |||||
nav | |||||
{ | |||||
font-size: 85%; | |||||
margin: 0 0 0 0; | |||||
} | |||||
.right | |||||
{ | |||||
text-align: right; | |||||
} | |||||
.noborder | |||||
{ | |||||
border: 0; | |||||
} | |||||
#notice { | |||||
background-color: green; | |||||
color: white; | |||||
padding: 10px 20px; | |||||
} | |||||
.menu { | |||||
margin: 0; | |||||
padding: 0; | |||||
} | |||||
.menu li { | |||||
list-style-type: none; | |||||
display: inline; | |||||
margin: 20px 0; | |||||
padding: 0 10px 0 0; | |||||
} | |||||
@media print { | |||||
.noprint, #footer, .nav, nav | |||||
{ | |||||
display: none; | |||||
} | |||||
body | |||||
{ | |||||
margin: 0 auto; | |||||
color: black; | |||||
} | |||||
a, a:visited { | |||||
background-color: #fff; | |||||
} | |||||
} |
@@ -0,0 +1,8 @@ | |||||
%h1 Authorities | |||||
%table | |||||
- auths.each do |auth| | |||||
%tr | |||||
%td | |||||
%a{ :href => slug(auth['authority_name']) } | |||||
= auth['authority_name'] |
@@ -0,0 +1,42 @@ | |||||
%h1= auth['authority_name'] | |||||
%h2 Summary | |||||
%table | |||||
%thead | |||||
%tr | |||||
%th Status | |||||
%th Decision | |||||
%th Appeal status | |||||
%th Appeal decision | |||||
%th Quantity | |||||
%tbody | |||||
- summary.each do |row| | |||||
%tr | |||||
%td= cleanup(row['status']) | |||||
%td= cleanup(row['decision']) | |||||
%td= cleanup(row['appeal_status']) | |||||
%td= cleanup(row['appeal_decision']) | |||||
%td= row['qty'] | |||||
%h2 Applications | |||||
%table | |||||
%thead | |||||
%tr | |||||
%th Received | |||||
%th Reference | |||||
%th Address | |||||
-# %th Proposal | |||||
%th Status | |||||
%th Decision | |||||
- apps.each do |app| | |||||
%tr | |||||
%td= short_date(app['date_received']) | |||||
%td | |||||
%a{ href: app['info_url']} | |||||
= app['council_reference'] | |||||
%td= app['address'] | |||||
-# %td= app['description'] | |||||
%td= cleanup(app['status']) | |||||
%td= cleanup(app['decision']) |
@@ -0,0 +1,22 @@ | |||||
%h2 Latest decisions | |||||
%table | |||||
%thead | |||||
%tr | |||||
%th Authority | |||||
%th Reference | |||||
%th Date | |||||
%th Address | |||||
%th Decision | |||||
%tbody | |||||
- decisions.each do |app| | |||||
%tr | |||||
%td | |||||
%a{ :href => "/authorities/#{ slug(app['authority_name'])}" } | |||||
= app['authority_name'] | |||||
%td | |||||
%a{ href: app['info_url']} | |||||
= app['council_reference'] | |||||
%td= short_date(app['date_decision']) | |||||
%td= app['address'] | |||||
%td= app['decision'] | |||||
@@ -0,0 +1,22 @@ | |||||
!!!5 | |||||
%html | |||||
%head | |||||
%title InLink kiosks planning applications | |||||
%link{ :href => '/style.css', :rel => 'stylesheet'} | |||||
%body | |||||
#main | |||||
#header | |||||
%h1 InLink kiosks planning applications | |||||
%ul.menu | |||||
%li | |||||
%a{ :href => '/' } | |||||
Home | |||||
%li | |||||
%a{ :href => '/authorities' } | |||||
Authorities | |||||
= yield | |||||
#footer | |||||
%a{ :href => 'https://twitter.com/adrianshort'} | |||||
@adrianshort made this. |