635 snippets – displaying 1–30

Selecting a JavaScript Chart Library

Which JavaScript library should I use for generating charts?

http://chartjs.org

  • +11 000 followers on Github
  • +200 issues on Github
  • Supports modern browsers and IE 8: http://caniuse.com/#feat=canvas

http://c3js.org/

  • based on D3.js
  • +3000 followers on Github
  • +150 issues on Github

http://d3js.org/

  • unlimited possibilities
  • unlimited complexity
  • unlimited popularity
  • you need to write your own reusable d3.js components
  • supports Firefox, Chrome, Safari, Opera, IE9+, Android and iOS. Parts of D3 may work in older browsers.

http://nvd3.org/

  • based on D3.js
  • +3000 followers on Github
  • +250 issues on Github

http://www.flotcharts.org/

  • Works with Internet Explorer 6+, Chrome, Firefox 2+, Safari 3+ and Opera 9.5+
  • requires jQuery
  • +3500 followers on Github
  • +250 issues on Github

http://g.raphaeljs.com/

  • +1400 followers on Github
  • +110 issues on Github
  • supports Firefox 3.0+, Safari 3.0+, Opera 9.5+ and Internet Explorer 6.0+.

http://www.fusioncharts.com/

  • “23 000 customers”
  • price is “as much as you can pay”

http://www.highcharts.com/

  • Free for non-commercial projects
  • HTML5
  • “tens of thousands of developers”
  • supports line, spline, area, areaspline, column, bar, pie, scatter, angular gauges, arearange, areasplinerange, columnrange and polar chart

Remember to check the license before selecting one…

Getting Started With React.js and Rails

Why React.js?

  • React ~35kb vs. Amber.js ~100kb
  • Easy to learn compared to Ember.js and Angular.js
  • Supports server-side rendering
  • Great performance

Installation

Gemfile:

gem 'active_model_serializers' # You probably want this gem too...
gem 'react-rails', '~> 1.0.0.pre', github: 'reactjs/react-rails'

From the console run:

bundle
rails g react:install

Make sure you have this in app/assets/javascript/application.js:

# ...
#= require react
#= require_tree components

Add this to config/environments/production.rb

Rails.config.react.variant = :production

And this to config/environments/development.rb

Rails.config.react.variant = :development

Hello World

Create app/assets/javascripts/components/hello.jsx.coffee (note the file extension):

###* @jsx React.DOM ###

window.Hello = React.createClass
  render: ->
    `<div>{this.props.name}</div>`

app/views/layouts/application.html.erb

<html><div data-react-class="Hello" data-react-props=<%= { name: 'John' }.to_json %>/>
</html>

Troubleshooting

  • Unexpected token ‘<’ Error *

Did you forget to add this to the top of your React component file (.js.jsx)?

/** @jsx React.DOM */

or this to your CoffeeScript component (.jsx.coffee):

###* @jsx React.DOM ###

  • Target container is not a DOM element. *

Does the DOM element exist?

Did you forget to call React.renderComponent in jQuery’s $(document).ready?

Adjacent XJS elements must be wrapped in an enclosing tag

Multiple nodes need a parent element:

<ul> // Doesn't work without <ul> wrapper
  <li></li>
  <li></li>
</ul>

  • Still doesn’t work? *

react-rails is not stable; expect it to break.

Gotchas

How to configure a no-www redirection on Amazon AWS (S3 and Cloudfront)

How do you configure a site hosted on Amazon AWS, e.g. a static website, to redirect from “www” to the “no-www” domain (aka “naked domain”)? The secret tool is the AWS CLI.

For example, this creates a redirection from www.×.com to x.com for a bucket named www.×.com:

aws s3api put-bucket-website --bucket www.x.com --website-configuration '{
    "RedirectAllRequestsTo": {
        "HostName": "x.com"
    }
}'

There’s no need for wwwizer.com or Route 53 with this configuration.

Use this command to check that the configuration is set properly:

aws s3api get-bucket-website --bucket www.x.com

World's Smallest Screenshot Server

require 'base64'
require 'selenium-webdriver'

class ScreenshotMiddleware
  def initialize(app)
    @app = app
  end

  def screenshot(url, width, height, file)
    begin
      driver = Selenium::WebDriver.for :firefox
      driver.manage.window.resize_to(width, height)
      driver.navigate.to url
      driver.save_screenshot("screenshots/#{file}")
      file
    ensure
      driver.quit
    end
  end

  def call(env)
    req = Rack::Request.new(env)
    width = req.params.fetch('width') { 1024 }
    height = req.params.fetch('height') { 768 }
    url = req.params.fetch('url')
    file = Base64.urlsafe_encode64(req.params.inspect) + ".png"
    screenshot(url, width, height, file)
    env['PATH_INFO'] = "/#{file}"
    @app.call(env)
  end
end

use ScreenshotMiddleware
run Rack::URLMap.new({
  "/" => Rack::Directory.new('screenshots')
})

Also see How to capture screenshots with Selenium, Ruby and Firefox.

Screenshot server API

How to use the AWS Command Line Interface Documentation

How to use the AWS Command Line Interface Documentation.

Cloudfront is not supported at the moment, see list of supported services for details.

Install the Amazon AWS command line client

$ pip install awscli
# or
$ sudo easy_install awscli

Now you need to configure the client:

$ aws configure

How to create an S3 bucket

aws s3 mb s3://xxx

How to list S3 buckets

$ aws s3 ls

How to configure a website

$ aws s3 website help

How to get the website configuration

 $ aws s3api get-bucket-website --bucket x.com

How to configure redirection for your website

This creates a redirection from x.com to www.×.com:

aws s3api put-bucket-website --bucket x.com --website-configuration '{
    "RedirectAllRequestsTo": {
        "HostName": "www.x.com"
    }
}'

How to set the error document

$ aws s3 website s3://xxx --index-document index.html --error-document 404/index.html

How to upload a website to S3

$ aws s3 sync ~/mysite s3://mysite --delete --cache-control \"max-age=3600\" --acl public-read --exclude *.txt

Note that the command will:

  • delete files from S3 that don’t exist locally.
  • set max-age header to 3600
  • allow anyone to access the files
  • exclude *.txt files

How to use Rails Engines

Create a new engine named x:

$ rails plugin new x --mountable

Load the engine by modifying Gemfile:

gem 'x', path: 'engines/x'

Mount the engine as root in config/routes.rb:

mount X::Engine => ”/”, as: ’root’

Optionally, allow the engine to override views and assets by adding this to config/application.rb:

ApplicationController.prepend_view_path Rails.root.join('engines', 'x', 'app', 'views')

%w(stylesheets javascripts images).each do |dir|
  Rails.configuration.assets.paths.unshift Rails.root.join('engines', 'x', 'app', 'assets', dir)
end

Resources

https://github.com/shageman/the_next_big_thing
http://pivotallabs.com/migrating-from-a-single-rails-app-to-a-suite-of-rails-engines/
http://pivotallabs.com/unbuilt-rails-dependencies-how-to-design-for-loosely-coupled-highly-cohesive-components-within-a-rails-application/
http://pivotallabs.com/experience-report-engine-usage-that-didn-t-work/
http://assets.pivotallabs.com/1439/original/2012_06_12_wrangling_large_rails_codebases.pdf
http://microservices.io/patterns/monolithic.html

Web Microframework Benchmark

Results on an old MacBook Air:

Ruby 2.1.0 + Hobbit + Hat + puma (-t 8 -w 2) - ~100-150 req/s (Hat = Hobbit app template with i18n, asset pipeline, etc)
Ruby 2.1.0 + Hobbit + Hat custom + puma (-t 8 -w 2) - ~1500 req/s (Hat without asset pipeline)
Ruby 2.1.0 + Hobbit + puma (-t 8 -w 2) - ~1600 req/s
Ruby 2.1.0 + rack + puma (-t 8 -w 2) - ~1600 req/s
Golang 1.3.1 + net/http - ~2700 req/s
Elixir 1.0.0 + Phoenix 0.4.1 - ~1300 req/s
Clojure 1.6.0 + ring 1.3.1 - ~5000 req/s
Clojure 1.6.0 + ring 1.3.1 + slim - ~270 req/s

YMMV.

Cuba Hello World

rubycubachristianVersion 2

http://cuba.is/

app.rb:

require "cuba"
#require "rack/protection"

#Cuba.use Rack::Session::Cookie, :secret => "__a_very_long_string__"
#Cuba.use Rack::Protection

Cuba.define do
  # only GET requests
  on get do
    # /
    on root do
      res.write "Home"
    end
  end
end

config.ru:

require "./app"
require 'sprockets'

map '/assets' do
  env = Sprockets::Environment.new
  env.append_path 'assets/javascripts'
  env.append_path 'assets/stylesheets'
  env.append_path 'assets/images'
  run env
end

run Cuba

Gemfile:

source 'https://rubygems.org'
gem 'cuba'
gem 'sprockets'
gem 'puma'

Anonymous hello world benchmark:

Node.js - 27 000 req/s
Ruby cuba - 17 000 req/s
Ruby hobbit - 17 000 req/s
Ruby rack - 25 000 req/s

Yes, Ruby is very slow.

How to prepend to directory to the view path in Rails (3, 4, etc)

Put this in an initializer e.g. config/initializers/parameterization.rb to load different views for different apps that use the same codebase:

APP_NAME = ENV['APP']
ApplicationController.prepend_view_path Rails.root.join('app', 'views', APP_NAME)

prepend_view_path can also be called e.g. once per request before rendering the view to have different view templates for each subdomain, user, cat, etc.

How to Implement Client-Cert Authentication with Apache (Smart Cards, HST-kortti, FINEID)

The goal is to automatically sign in users who have an SSL client-certificate issued by a known certificate authority, e.g. Finnish Väestörekisteri (VRK).

First, we’re going to install and configure Apache 2.2 for client-cert authentication.

Install Apache 2.2

$ brew install -v httpd22.rb 2>&1

Download VRK Certificates

In this example we’re using VRK’s root test certificate. Make sure you pick the right certificate for your purposes, e.g. the one for healthcare professionals.

VRK certificates can be downloaded here:
http://fineid.fi/default.aspx?docid=2293&site=10&id=597

$ cd /usr/local/etc/apache2/2.2/
$ mkdir ssl
$ wget http://vrk.fineid.fi/certs/vrktestc.crt
$ mv vrktestc.crt ssl/
# Convert from DER to PEM format
$ openssl x509 -in ssl/vrktestc.crt -inform DER -outform PEM -out ssl/vrktestc.pem

Download VRK Revocation List

Revocation lists for VRK’s client certificates can be found here:
http://fineid.fi/default.aspx?docid=2330&site=10&id=588#whereistherevocationlist

$ cd /usr/local/etc/apache2/2.2/
$ wget http://proxy.fineid.fi/crl/vrkcqcc.crl
$ mv vrkcqcc.crl ssl/
# Convert from DER to PEM format
$ openssl x509 -in ssl/vrkcqcc.crl -inform DER -outform PEM -out ssl/vrkcqcc.pem

I was unable to get openssl or Apache to read the revocation list, so the other option is to query VRK’s LDAP servers for revoked certificates.

Generate Self-Signed Certificate for Apache

If you have a real certificate, skip this part.

$ cd /usr/local/etc/apache2/2.2/
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ssl/server.key -out ssl/server.crt

Configure Apache

<VirtualHost xxx:443>

ProxyPreserveHost On
ProxyPass / http://0.0.0.0:8888/

SSLCertificateFile "/usr/local/etc/apache2/2.2/ssl/server.crt"
SSLCertificateKeyFile "/usr/local/etc/apache2/2.2/ssl/server.key"
SSLCACertificateFile "/usr/local/etc/apache2/2.2/ssl/vrktestc.pem" 
SSLVerifyClient optional # none, optional, require and optional_no_ca
SSLVerifyDepth 2 # Root certificate requires depth >= 2

# Let Rails know we’re using HTTPS
RequestHeader set X_FORWARDED_PROTO 'https'

#
# Forward certificate information to application
# See http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#envvars
#
# Subject's certificate
RequestHeader set SSL_CLIENT_S_DN "%{SSL_CLIENT_S_DN}s"
RequestHeader set SSL_SERVER_S_DN_OU "%{SSL_SERVER_S_DN_OU}s"
# Issuer's certificate
RequestHeader set SSL_CLIENT_I_DN "%{SSL_CLIENT_I_DN}s"
# Verification status: NONE, SUCCESS, GENEROUS or FAILED:reason
RequestHeader set SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s"


# Optional settings
#
# Require issuer of certificate to have a specific O and OU:
<Location />
    SSLRequire %{SSL_CLIENT_I_DN_O} eq "Vaestorekisterikeskus TEST" and \
           %{SSL_CLIENT_I_DN_OU} eq "Terveydenhuollon testiammattivarmenteet"
</Location>

# Export SSL and certificate variables
# SSLOptions +ExportCertData +StrictRequire +StdEnvVars

# Revocation list
# NOTE: disabled because of “Unable to configure X.509 CRL storage for certificate revocation”
#SSLCARevocationFile "/usr/local/etc/apache2/2.2/ssl/vrkcqcc.crl"

Troubleshooting & FAQ

How can I verify that the SSL-certificate is set up properly?

$ openssl s_client -connect localhost:443 -showcerts

Acceptable client certificate CA names
/C=FI/ST=Finland/O=Vaestorekisterikeskus TEST/OU=Certification Authority Services/OU=Varmennepalvelut/CN=VRK TEST Root CA

Why am I getting SSL handshake failures?

Invalid self-signed certificate?

Removing the smart card or disconnecting the smart card reader will close the browser

This means you need to expire the session when the browser is closed. In a Rails application you need to remove expire_after from session_store.rb.

Browsers issues

Browers might perform client-cert authentication in different ways. Many browsers have bugs related to client-cert authentication.

Inserting the smart card after starting the browser might mean the SSL client certificate’s information is not sent to the server.

If you’re having issues, the best solution is usually to restart the browser.

Apache is unable to read the revocation list (CRL)

VRK’s revocation certificate is not in the format required by Apache’s mod_ssl, i.e. the file doesn’t begin with:
-BEGIN X509 CRL——-

The file is binary, so the CRL list is probably in DER format. However, converting the file to PEM format doesn’t work:

$ openssl x509 -in ssl/vrkcqcc.crl -inform DER -outform PEM -out ssl/vrkcqcc.pem

Reading the CRL file seems to work fine:

$ openssl crl -in ssl/vrkcqcc.crl -text -noout -inform DER

The solution for getting revocation to work is to use an LDAP search for revocation. Apache doesn’t support this.

Implementing Client-Cert Authentication in Web Applications

An application that needs to support client-cert authentication should implement the following system and user stories:

  • Enable client-cert authentication (user)

As a user I want to enable client-cert authentication, so that I don’t need to sign in manually.

  • Disable client-cert authentication (user)
  • Sign in user with client certificate (system)

In Ruby on Rails you can access the client-certification information through the headers set by Apache:

request.headers['HTTP_SSL_CLIENT_S_DN'] == user's distinguished name (DN)
request.headers['HTTP_SSL_CLIENT_I_DN'] == issuer's DN
request.headers['HTTP_SSL_CLIENT_VERIFY'] == 'SUCCESS'

Simple Ruby Server With Rack

Create a file named config.ru:

run lambda { |env|
  [200, {"Content-Type" => "text/html"}, [view(env)]]
}

def view(env)
  res = ""
  res << "<html><body><pre>"
  env.sort.each do |key, value|
    res << "#{key}: #{value}"
    res << "\n"
  end
  res << "</pre></body></html>"
  res
end

Start the server with rackup:

$ rackup

Access http://localhost:9292 to see the request headers.

ActiveRecord's write_attribute is deprecated

ActiveRecord’s write_attribute is deprecated, so now you only have one hundred other ways of assigning attributes.

My favorite for dynamic assignment of attributes is:

class Dog
  def crap=(poo)
     self[:trash] = poo # don't try to use self.attributes[:trash] here you fool.
  end

  def crap
     self[:trash] # don't try to use self.attributes[:trash] here you fool.
  end
end

Sprockets for Sinatra

Features:

  • asset pipeline based on Sprockets
  • precompilation
  • versioning of assets

The “concern” that you need to include in your application:

#
# Asset pipeline for Sinatra based on Sprockets.
#
# NOTE: In production use rake assets:precompile to compile assets and generate an
# asset version file.
#
module AssetsConcern
  extend ActiveSupport::Concern

  included do
    set :assets_prefix, '/assets'
    set :assets_path, File.join(App.root, 'public', assets_prefix)
    set :assets_precompile, true
  end

  module ClassMethods
    #
    # Returns the current version.
    #
    def asset_version
      @@asset_version ||= read_asset_version
    end

    def read_asset_version
      file = 'public/assets/version'
      if File.exist?(file)
        File.read(file).to_i
      else
        nil
      end
    end

    #
    # Returns the path to the assets.
    #
    def asset_path(name, type)
      if App.asset_version
        file = "/assets/#{name}-#{App.asset_version}.#{type}"
      else
        file = "/assets/#{name}.#{type}"
      end
    end

    def sprockets
      require "yui/compressor"
      project_root = File.expand_path(File.dirname(__FILE__))
      assets = Sprockets::Environment.new(project_root)
      # Include js, css, and bower managed components
      %w(bower_components app/js app/css).each do |path|
        assets.append_path(File.join(App.root, path))
      end
      assets
    end
  end
end

The Rake task for compilication of assets:

namespace :assets do
  task :precompile do
    version = Time.now.to_i 
    App.sprockets['application.js'].write_to("public/assets/application-#{version}.js")
    App.sprockets['application.css'].write_to("public/assets/application-#{version}.css")
    File.open('public/assets/version', 'w') { |f| f << version }
    puts "Done... Version #{version}"
  end
end

The view template:

= css_tag(:application)
= js_tag(:application)

How to Implement Flash for Sinatra (or Any Other Framework)

Implementing Rails’ “Flash concept” for Sinatra is easy.

This example gives you:

  • Flash messages that are translated by the I18n library
  • Simple code. For example rack-flash is not needed.
  • Cachable pages. Storing your application’s flash messages in a cookie means you can cache the whole page. There are no user specific flash messages in the response HTML.

Implementation

Ruby code:

def flash(key, value)
  fail "Invalid key '#{key}'" unless [ :info, :error ].include?(key)
  response.set_cookie "flash_#{key}", value: I18n.t(value), path: '/'
end

Put the code in a helper or controller.

Coffeescript code:

class Flash
  constructor: (@flash_holder, @cookie_prefix) ->
    @flash_holder ?= '#flash'
    @cookie_prefix ?= 'flash_'

  show: ->
    for key in ['info', 'error']
      # Read cookie, e.g. flash_info
      name = @cookie_prefix + key
      value = $.cookie(name)
      if value
        # Set flash holder contents to cookie value
        $(@flash_holder).attr('class', name).html(value).show('fast')
        $.removeCookie(name)

$ ->
  # Display the flash message
  new Flash().show()

  # You can customize the behavior by passing parameters to the constructor, e.g.
  new Flash('#flash_holder', 'cookie_prefix').show()

HTML code:

<div id="#flash"></div>

SASS code:

#flash
  display: none

.flash_info
  color: darkgreen

.flash_error
  color: darkred

Usage

In your controller:

get '/' do
  flash :info, 'login.failed'
end

Dependencies

How to color your bash prompt red in production

bashcolorredchristianVersion 3

How to color your bash prompt red in production:

export RED="\[\e[1;31m\]"
export NORMAL="\[\e[0m\]"

# user@host: ~/directory $
BASE_PROMPT="$RED\u@\h$NORMAL: \w "

# Root prompt should have #
if [[ $EUID == 0 ]] ; then
  export PS1="$BASE_PROMPT#"
else
  export PS1="$BASE_PROMPT\$"
fi

Put it in /etc/profile.d/promptcolor.sh for all users to see the prompt in color.

Script also helps with lowering anxiety levels.

Checking For JavaScript Errors or e.g. XSS Attacks With Capybara

Use the following code to check for JavaScript errors, or XSS vulnerabilities:

class IntegrationSpec < MiniTest::Spec
  def assert_no_js_errors
    assert_equal 0, page.driver.error_messages.size, page.driver.error_messages.ai
  end

  def assert_no_alerts(types = [:alert, :confirm, :prompt])
    types.each do |type|
      alerts = page.driver.send(:"#{type}_messages")
      assert_equal 0, alerts.size, alerts.ai
    end
  end
end

Test plan

  • Insert XSS hacks into database
  • Write integration tests that visit all pages

Requires

  • capybara
  • capybara-webkit

Rails Services

railsserviceschristianVersion 10

Put your business logic in a service layer, not in your controllers, helpers, models, or anywhere else.

app/services/service.rb:

#
# Base service class.
#
module Service
  extend ActiveSupport::Concern

  included do
  end

  module ClassMethods
    def call(*args)
      new(*args).call
    end
  end
end

app/services/create_report.rb:

#
# Create order user story.
#
class CreateOrder
  include Service

  def initialize(user, product)
    @user = user
    @product = product
    validate
  end

  def call
    Order.transaction do
      ...
    end
  end

  def validate
    ...
  end
end

Usage:

class OrdersController # or OrderJob
  def create
    ...
    @order = CreateOrder.call(user, product)
    ...
  end
end

Naming conventions:

  • app/services/verb_subject.rb
  • class VerbSubject
  • app/services/namespace/verb_subject.rb
  • class Namespace::VerbSubject

Benefits:

  • maintainability
  • readability
  • testability
  • etc