Permalink
Browse files

this.call(sky)

  • Loading branch information...
thejefflarson committed Sep 7, 2010
1 parent 0fc55c7 commit ed6e858f3d8444ad0d8ec51c22b2f22dd8dd87b1
Showing with 2,310 additions and 11 deletions.
  1. +1 −0 .gitignore
  2. +13 −11 README
  3. +10 −0 Rakefile
  4. +9 −0 app/controllers/application_controller.rb
  5. +42 −0 app/controllers/stats_controller.rb
  6. +3 −0 app/helpers/application_helper.rb
  7. +2 −0 app/helpers/stats_helper.rb
  8. +77 −0 app/models/stat.rb
  9. +31 −0 app/views/layouts/stats.html.erb
  10. +2 −0 app/views/stats/index.html.erb
  11. +16 −0 config/assets.yml
  12. +110 −0 config/boot.rb
  13. +14 −0 config/environment.rb
  14. +17 −0 config/environments/development.rb
  15. +28 −0 config/environments/production.rb
  16. +32 −0 config/environments/test.rb
  17. +7 −0 config/initializers/backtrace_silencers.rb
  18. +7 −0 config/initializers/cookie_verification_secret.rb
  19. +10 −0 config/initializers/inflections.rb
  20. +5 −0 config/initializers/mime_types.rb
  21. +21 −0 config/initializers/new_rails_defaults.rb
  22. +5 −0 config/locales/en.yml
  23. +6 −0 config/routes.rb
  24. +16 −0 db/migrate/20100706192337_create_stats.rb
  25. +9 −0 db/migrate/20100707202439_remove_seen_urls_from_stats.rb
  26. +9 −0 db/migrate/20100708014720_add_indexes_to_urls.rb
  27. +25 −0 db/schema.rb
  28. +7 −0 db/seeds.rb
  29. BIN db/test.sqlite3
  30. +2 −0 doc/README_FOR_APP
  31. +13 −0 lib/tasks/db_utils.rake
  32. +12 −0 lib/tasks/track.rake
  33. +30 −0 public/404.html
  34. +30 −0 public/422.html
  35. +30 −0 public/500.html
  36. 0 public/favicon.ico
  37. BIN public/images/rails.png
  38. +27 −0 public/javascripts/app/app.js
  39. +1 −0 public/javascripts/app/models/ping-client.js
  40. +18 −0 public/javascripts/app/templates/table.jst
  41. +10 −0 public/javascripts/app/views/get_dates.js
  42. +22 −0 public/javascripts/app/views/pixel-ping.js
  43. +67 −0 public/javascripts/lib/model.js
  44. +45 −0 public/javascripts/lib/rest_client.js
  45. +52 −0 public/javascripts/lib/view.js
  46. +6 −0 public/javascripts/pixeltracker.js
  47. +62 −0 public/javascripts/vendor/Base.js
  48. +223 −0 public/javascripts/vendor/date-en-US.js
  49. +154 −0 public/javascripts/vendor/jquery.min.js
  50. +16 −0 public/javascripts/vendor/json_date.js
  51. +713 −0 public/javascripts/vendor/underscore.js
  52. +5 −0 public/robots.txt
  53. +86 −0 public/stylesheets/application.css
  54. +4 −0 script/about
  55. +3 −0 script/console
  56. +3 −0 script/dbconsole
  57. +3 −0 script/destroy
  58. +3 −0 script/generate
  59. +3 −0 script/performance/benchmarker
  60. +3 −0 script/performance/profiler
  61. +3 −0 script/plugin
  62. +3 −0 script/runner
  63. +3 −0 script/server
  64. +4 −0 test/factories.rb
  65. +20 −0 test/functional/stats_controller_test.rb
  66. +9 −0 test/performance/browsing_test.rb
  67. +41 −0 test/test_helper.rb
  68. +4 −0 test/unit/helpers/stats_helper_test.rb
  69. +43 −0 test/unit/stat_test.rb
View
@@ -1,4 +1,5 @@
*.log
+*.sqlite3
config/database.yml
config/deploy.rb
config/*.json
View
24 README
@@ -1,19 +1,21 @@
=
- ___ _ _ ___ _
- | _ (_)_ _____| | | _ (_)_ _ __ _
- | _/ \ \ / -_) | | _/ | ' \/ _` |
- |_| |_/_\_\___|_| |_| |_|_||_\__, |
- |___/
+ ____ _ __ ____
+ / __ \(_)_ _____ / / / __ \____ ____ ____ _
+ / /_/ / /| |/_/ _ \/ / / /_/ / __ \/ __ \/ __ `/
+ / ____/ /_> </ __/ / / ____/ /_/ / / / / /_/ /
+ /_/ /_//_/|_|\___/_/ /_/ \____/_/ /_/\__, /
+ /____/
o . _______ _______
\_ 0 /______//______/| @_o
/\_, /______//______/ /\ <- you are here.
| \ | || | / |
- pixeltracker is the reference implementation for the Pixel Ping stats collector.
- It's written in rails 2.3.8 and is useful when you need to get up and running
- quickly.
+ Pixel Pong is the reference implementation for the Pixel Ping stats collector.
+ See Pixel Ping:
+
+ http://github.com/documentcloud/pixel-ping
== Guided Tour
@@ -24,8 +26,8 @@
Pixel Ping's configuration files are stored in:
pixel-ping.#{Rails.env}.json
-
+
Once you have filled out the details you can run rake pixel:track to start an
- instance of Pixel Ping. After Pixel Ping starts boot this app and start collecting
- stats.
+ instance of Pixel Ping. After Pixel Ping starts, boot this app and start
+ collecting stats.
View
@@ -0,0 +1,10 @@
+# Add your own tasks in files placed in lib/tasks ending in .rake,
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
+
+require(File.join(File.dirname(__FILE__), 'config', 'boot'))
+
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+require 'tasks/rails'
@@ -0,0 +1,9 @@
+# Filters added to this controller apply to all controllers in the application.
+# Likewise, all the methods added will be available for all controllers.
+
+class ApplicationController < ActionController::Base
+ helper :all # include all helpers, all the time
+
+ # Scrub sensitive parameters from your log
+ # filter_parameter_logging :password
+end
@@ -0,0 +1,42 @@
+class StatsController < ApplicationController
+ # GET /stats
+ # GET /stats.xml
+ def index
+ @today = Date.today.to_time
+ conditions = ["created_at > ? and created_at <= ?", @today, @today + 1.day]
+ conditions = ["created_at > ? and created_at <= ?", Time.parse(params[:start_date]).to_date.to_time, Time.parse(params[:end_date]).to_date.to_time + 1.day] if params[:start_date] && params[:end_date]
+ first = Stat.first(:order => "updated_at DESC")
+ @last_updated = first ? first.updated_at.strftime("%B %d, %Y %l:%M%p").gsub(/AM/, "am").gsub(/PM/, "pm") : nil
+ respond_to do |format|
+ format.html # index.html.erb
+ format.json {
+ render :json => Stat.aggregate.all(:conditions => conditions)
+ }
+ end
+ end
+
+ # GET /stats/1
+ # GET /stats/1.xml
+ def show
+ @stat = Stat.find(params[:id])
+
+ respond_to do |format|
+ format.html # show.html.erb
+ format.xml { render :xml => @stat }
+ end
+ end
+
+ # POST /stats
+ # POST /stats.xml
+ def create
+ saved = Stat.track(params[:json], params[:secret])
+ respond_to do |format|
+ if saved
+ format.json { render :text => "OK", :status => :ok }
+ else
+ format.json { render :json => @stat.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+end
@@ -0,0 +1,3 @@
+# Methods added to this helper will be available to all templates in the application.
+module ApplicationHelper
+end
@@ -0,0 +1,2 @@
+module StatsHelper
+end
View
@@ -0,0 +1,77 @@
+class Stat < ActiveRecord::Base
+ validates_presence_of :url, :hits
+ validate_on_create :log_hits?
+ validate :url_format
+ named_scope :aggregate, :order => "hits DESC", :select => ["sum(hits) as hits, url, title"], :group => :url
+
+ def title
+ t = read_attribute(:title)
+ if t.nil?
+ begin
+ req = Curl::Easy.new(url)
+ req.perform
+ title = Nokogiri::HTML.parse(req.body_str).css('title').text
+ write_attribute(:title, title)
+ # catch bad urls
+ rescue Curl::Err::HostResolutionError
+ write_attribute(:title, "Inaccessible URL")
+ ensure
+ save
+ end
+ end
+ write_attribute(:title, "No Title") if read_attribute(:title).blank?
+ read_attribute(:title)
+ end
+
+ private
+
+ def url_format
+ u = URI.parse url
+ case
+ when u.scheme.nil? then errors.add(:url, "no scheme")
+ when u.host.nil? then errors.add(:url, "no host")
+ end
+ rescue URI::BadURIError, URI::InvalidURIError
+ errors.add(:url, "bad url")
+ end
+
+ def record_todays_date
+ self.date_for = Date.today
+ end
+
+ def log_hits?
+ record_todays_date
+ if Stat.exists? :url => url, :date_for => date_for
+ stat = Stat.first(:conditions => {:url => url, :date_for => date_for})
+ self.id = stat.id
+ new_hits = hits
+ reload
+ @new_record = false
+ errors.clear
+ increment(:hits, new_hits)
+ end
+ true
+ end
+
+ public
+
+ def self.track(json, secret)
+ raw_stats = JSON.parse(json)
+ if secret == PIXEL_SECRET
+ raw_stats.each do |component, hits|
+ if component.include? ""
+ bits = component.split ""
+ title = bits.shift
+ url = bits.pop
+ else
+ title = nil
+ url = component
+ end
+ stat = Stat.new(:title => title, :url => url, :hits => hits)
+ stat.save
+ end
+ return true
+ end
+ false
+ end
+end
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <link rel="stylesheet" href="http://www.propublica.org/css/960/reset.css" type="text/css" media="all" charset="utf-8" />
+ <link rel="stylesheet" href="http://www.propublica.org/css/960/propublica-text.css" type="text/css" media="all" charset="utf-8" />
+ <link rel="stylesheet" href="http://www.propublica.org/css/master.css" type="text/css" media="screen" charset="utf-8" />
+ <link rel="stylesheet" href="http://www.propublica.org/css/print.css" type="text/css" media="print" charset="utf-8" />
+ <%= include_stylesheets :all %>
+ <%= include_javascripts :all %>
+<title>Pixel Ping - ProPublica</title>
+</head>
+<body>
+ <div id="content">
+ <div class="wrapper">
+ <h1>
+ Pixel Ping
+ </h1>
+ <div id="toolbar">
+ <a class="button" id="get_dates"><b class="o"><b class="m"><b>Get Dates</b></b></b></a>
+ <div class="dates">
+ <label for="from">From: </label><input id="from" value="<%= @today.to_date %>">
+ <label for="from">To: </label><input id="to" value="<%= @today.to_date %>">
+ </div>
+ </div>
+ </div>
+ <div class="wrapper">
+ <%= yield %>
+ </div>
+ </div>
+</body>
+</html>
@@ -0,0 +1,2 @@
+<div id="pixel-ping-view"></div>
+<p><em>Last Updated: <%= @last_updated if @last_updated %></em></p>
View
@@ -0,0 +1,16 @@
+embed_assets: on
+
+javascripts:
+ all:
+ - public/javascripts/vendor/*.js
+ - public/javascripts/*.js
+ - public/javascripts/app/app.js
+ - public/javascripts/lib/*.js
+ - public/javascripts/app/models/*.js
+ - public/javascripts/app/views/*.js
+ - public/javascripts/app/templates/*.jst
+
+
+stylesheets:
+ all:
+ - public/stylesheets/*.css
View
@@ -0,0 +1,110 @@
+# Don't change this file!
+# Configure your app in config/environment.rb and config/environments/*.rb
+
+RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
+
+module Rails
+ class << self
+ def boot!
+ unless booted?
+ preinitialize
+ pick_boot.run
+ end
+ end
+
+ def booted?
+ defined? Rails::Initializer
+ end
+
+ def pick_boot
+ (vendor_rails? ? VendorBoot : GemBoot).new
+ end
+
+ def vendor_rails?
+ File.exist?("#{RAILS_ROOT}/vendor/rails")
+ end
+
+ def preinitialize
+ load(preinitializer_path) if File.exist?(preinitializer_path)
+ end
+
+ def preinitializer_path
+ "#{RAILS_ROOT}/config/preinitializer.rb"
+ end
+ end
+
+ class Boot
+ def run
+ load_initializer
+ Rails::Initializer.run(:set_load_path)
+ end
+ end
+
+ class VendorBoot < Boot
+ def load_initializer
+ require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
+ Rails::Initializer.run(:install_gem_spec_stubs)
+ Rails::GemDependency.add_frozen_gem_path
+ end
+ end
+
+ class GemBoot < Boot
+ def load_initializer
+ self.class.load_rubygems
+ load_rails_gem
+ require 'initializer'
+ end
+
+ def load_rails_gem
+ if version = self.class.gem_version
+ gem 'rails', version
+ else
+ gem 'rails'
+ end
+ rescue Gem::LoadError => load_error
+ $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
+ exit 1
+ end
+
+ class << self
+ def rubygems_version
+ Gem::RubyGemsVersion rescue nil
+ end
+
+ def gem_version
+ if defined? RAILS_GEM_VERSION
+ RAILS_GEM_VERSION
+ elsif ENV.include?('RAILS_GEM_VERSION')
+ ENV['RAILS_GEM_VERSION']
+ else
+ parse_gem_version(read_environment_rb)
+ end
+ end
+
+ def load_rubygems
+ min_version = '1.3.2'
+ require 'rubygems'
+ unless rubygems_version >= min_version
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
+ exit 1
+ end
+
+ rescue LoadError
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
+ exit 1
+ end
+
+ def parse_gem_version(text)
+ $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
+ end
+
+ private
+ def read_environment_rb
+ File.read("#{RAILS_ROOT}/config/environment.rb")
+ end
+ end
+ end
+end
+
+# All that for this:
+Rails.boot!
View
@@ -0,0 +1,14 @@
+
+RAILS_GEM_VERSION = '2.3.8' unless defined? RAILS_GEM_VERSION
+
+require File.join(File.dirname(__FILE__), 'boot')
+
+Rails::Initializer.run do |config|
+
+ config.gem "curb", :lib => "curl"
+ config.gem "jammit"
+ config.time_zone = 'Eastern Time (US & Canada)'
+
+end
+PIXEL_CONFIG = JSON.parse(File.read("#{Rails.root}/config/pixel-ping.#{Rails.env}.json")).symbolize_keys
+PIXEL_SECRET = PIXEL_CONFIG[:secret]
@@ -0,0 +1,17 @@
+# Settings specified here will take precedence over those in config/environment.rb
+
+# In the development environment your application's code is reloaded on
+# every request. This slows down response time but is perfect for development
+# since you don't have to restart the webserver when you make code changes.
+config.cache_classes = false
+
+# Log error messages when you accidentally call methods on nil.
+config.whiny_nils = true
+
+# Show full error reports and disable caching
+config.action_controller.consider_all_requests_local = true
+config.action_view.debug_rjs = true
+config.action_controller.perform_caching = false
+
+# Don't care if the mailer can't send
+config.action_mailer.raise_delivery_errors = false
Oops, something went wrong.

0 comments on commit ed6e858

Please sign in to comment.