├── .gitignore ├── .rbenv-vars-example ├── .ruby-version ├── Gemfile ├── Gemfile.lock ├── Procfile ├── README.md ├── app.rb ├── config.ru ├── index.erb └── public ├── favicon-down.png ├── favicon-up.png └── style.css /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .rbenv-gemsets 3 | .rbenv-vars 4 | .bundle 5 | -------------------------------------------------------------------------------- /.rbenv-vars-example: -------------------------------------------------------------------------------- 1 | PINGDOM_USERNAME=you@example.org 2 | PINGDOM_PASSWORD=password123 3 | PINGDOM_KEY=derp 4 | PINGDOM_CHECK_ID=1337 5 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.1.2 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | ruby '2.1.2' 3 | 4 | gem 'sinatra' 5 | gem 'sinatra-contrib' 6 | gem 'thin' 7 | gem 'pingdom-client', github: 'destroytoday/pingdom-client' 8 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GIT 2 | remote: git://github.com/destroytoday/pingdom-client.git 3 | revision: d4354ff72d52aefa072a5e861f7a5aead8e79bc7 4 | specs: 5 | pingdom-client (0.0.7.alpha) 6 | activesupport (~> 3.0.4) 7 | excon (~> 0.5.6) 8 | faraday (~> 0.5.7) 9 | i18n (~> 0.5.0) 10 | yajl-ruby (~> 1.2.1) 11 | 12 | GEM 13 | remote: https://rubygems.org/ 14 | specs: 15 | activesupport (3.0.20) 16 | addressable (2.2.8) 17 | backports (3.6.0) 18 | daemons (1.1.9) 19 | eventmachine (1.0.3) 20 | excon (0.5.8) 21 | faraday (0.5.7) 22 | addressable (~> 2.2.4) 23 | multipart-post (~> 1.1.0) 24 | rack (>= 1.1.0, < 2) 25 | i18n (0.5.4) 26 | multi_json (1.10.1) 27 | multipart-post (1.1.5) 28 | rack (1.5.2) 29 | rack-protection (1.5.3) 30 | rack 31 | rack-test (0.6.2) 32 | rack (>= 1.0) 33 | sinatra (1.4.5) 34 | rack (~> 1.4) 35 | rack-protection (~> 1.4) 36 | tilt (~> 1.3, >= 1.3.4) 37 | sinatra-contrib (1.4.2) 38 | backports (>= 2.0) 39 | multi_json 40 | rack-protection 41 | rack-test 42 | sinatra (~> 1.4.0) 43 | tilt (~> 1.3) 44 | thin (1.6.2) 45 | daemons (>= 1.0.9) 46 | eventmachine (>= 1.0.0) 47 | rack (>= 1.0.0) 48 | tilt (1.4.1) 49 | yajl-ruby (1.2.1) 50 | 51 | PLATFORMS 52 | ruby 53 | 54 | DEPENDENCIES 55 | pingdom-client! 56 | sinatra 57 | sinatra-contrib 58 | thin 59 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec thin start -p $PORT 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Uptime 2 | 3 | Uptime page for [destroytoday.com](http://destroytoday.com), using the style of warehouse lost time injury signs. 4 | 5 | ## Before deploying 6 | 7 | - fork and replace the `` and Typekit ID in `index.erb`. (This should be an ENV var, but I was young. Feel free to PR) 8 | 9 | [![](http://dstry.it/WMKp/image.png)](http://uptime.destroytoday.com) 10 | -------------------------------------------------------------------------------- /app.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra/base' 2 | require 'sinatra/reloader' 3 | require 'pingdom-client' 4 | 5 | class Uptime < Sinatra::Base 6 | configure do 7 | set :views, settings.root + '/' 8 | end 9 | 10 | configure :development do 11 | register Sinatra::Reloader 12 | end 13 | 14 | helpers do 15 | def client 16 | @client ||= Pingdom::Client.new( 17 | username: ENV['PINGDOM_USERNAME'], 18 | password: ENV['PINGDOM_PASSWORD'], 19 | key: ENV['PINGDOM_KEY'] 20 | ) 21 | end 22 | end 23 | 24 | get '/' do 25 | check = client.check(ENV['PINGDOM_CHECK_ID']) 26 | 27 | begin 28 | last_date = check.last_error_time.to_date 29 | rescue 30 | last_date = check.created.to_date 31 | end 32 | 33 | erb :index, locals: { 34 | status: check.status, 35 | days_since_downtime: (Date.today - last_date).to_i 36 | } 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | require './app' 2 | 3 | run Uptime 4 | -------------------------------------------------------------------------------- /index.erb: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html> 3 | <head> 4 | <meta content='text/html; charset=utf-8' http-equiv='Content-Type'> 5 | <meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'> 6 | 7 | <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0'> 8 | 9 | <title>Destroy Today - Uptime 10 | 11 | 12 | 13 | 14 | 15 | 16 | 25 | 26 | 27 |
28 |
29 |
30 |

31 | This website
32 | has worked
33 | <%= locals[:days_since_downtime] %> days
34 | without
35 | a lost time
36 | accident 37 |

38 |
39 |
40 |

Downtime is avoidable

41 |
42 |
43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /public/favicon-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/destroytoday/uptime/513504f2d7fad42e5829ef8e89db4307de199e6e/public/favicon-down.png -------------------------------------------------------------------------------- /public/favicon-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/destroytoday/uptime/513504f2d7fad42e5829ef8e89db4307de199e6e/public/favicon-up.png -------------------------------------------------------------------------------- /public/style.css: -------------------------------------------------------------------------------- 1 | @media screen and (max-device-width: 480px) { 2 | html { 3 | -webkit-text-size-adjust: 100%; 4 | -ms-text-size-adjust: 100%; 5 | } 6 | } 7 | 8 | html { 9 | height: 100%; 10 | } 11 | 12 | body { 13 | height: 100%; 14 | margin: 0; 15 | 16 | font: 400 100%/1.65 "Helvetica Neue", Helvetica, sans-serif; 17 | text-rendering: optimizeLegibility; 18 | 19 | color: white; 20 | 21 | overflow-x: hidden; 22 | } 23 | 24 | .is-up { 25 | background-color: #007954; 26 | } 27 | 28 | .is-down { 29 | background-color: #c00; 30 | } 31 | 32 | .wf-loading .webfont { 33 | visibility: hidden 34 | } 35 | 36 | .outer { 37 | display: table; 38 | margin: 0 auto; 39 | height: 100%; 40 | } 41 | 42 | .inner { 43 | display: table-cell; 44 | vertical-align: middle; 45 | text-align: center; 46 | } 47 | 48 | .sign { 49 | font-family: "gnuolane", "Helvetica Neue", Helvetica, sans-serif; 50 | font-size: 3em; 51 | font-weight: 700; 52 | line-height: 1.125em; 53 | letter-spacing: 2px; 54 | text-transform: uppercase; 55 | } 56 | 57 | @media screen and (min-width: 481px) { 58 | .sign { 59 | font-size: 4em; 60 | } 61 | } 62 | 63 | .sign p { 64 | margin: 0; 65 | } 66 | 67 | .sign strong { 68 | position: relative; 69 | top: -0.25em; 70 | 71 | display: inline-block; 72 | 73 | min-width: 2.5em; 74 | padding: 0 0.25em; 75 | 76 | font-size: 0.625em; 77 | line-height: 1.25em; 78 | text-align: right; 79 | background-color: white; 80 | color: #222; 81 | } 82 | 83 | .message { 84 | display: inline-block; 85 | padding: 0 0.625em; 86 | margin-top: 2em; 87 | 88 | font-style: italic; 89 | text-transform: uppercase; 90 | 91 | border-radius: 4px; 92 | background-color: white; 93 | } 94 | 95 | .is-up .message { 96 | color: #007954; 97 | } 98 | 99 | .is-down .message { 100 | color: #c00; 101 | } 102 | 103 | .message p { 104 | margin: 0; 105 | } 106 | --------------------------------------------------------------------------------