Spent Per Day

peter / 05.mar.2009

Scriptet jag bloggade om tidigare är nu klart och jag kallar det spent-per-day. Jag har använt mig av Gruff för att generera graferna och slutresultatet blev rätt stiligt.

Det ligger självklart på GitHub.

Vad gör scriptet?

Genererar grafer utifrån datat på översiktssidan på swedbank.se

Hur ser graferna ut?

Balance

Spend Per Day

Yahoo! Query Language

peter / 27.feb.2009

YQL gör det möjligt att hämta data från en mängd olika källor med ett SQL-liknande frågespråk. Man kan även använda det för sina egna applikationer.

Yahoo! kallar det:

A “mediator service” that enables developers to query, filter, and combine data across Yahoo! and beyond.

“YQL går att beskriva som ett API för den publika webben”

Exempel

YQL Fråga


SELECT url,title,abstract FROM search.web WHERE query="pizza"

REST URL (Returnerar JSONP)

1
2
http://query.yahooapis.com/v1/public/yql?q=select%20url%2Ctitle%2Cabstract
%20from%20search.web%20where%20query%3D%22pizza%22&format=json&callback=?

Ersätt det avslutande frågetecknet med din callback-metod. Om du använder jQuery kommer den att sköta det åt dig.

Kod

Övningsuppgiften på gårdagens Athegatorsdag bestod i att man med data returnerat av en YQL sökning på Flickr samt jQuery skulle skapa ett bildgalleri.

Ett enkelt exempel:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Latest images tagged Athega</title>
    <script type="text/javascript" 
      src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
    </script>
    <script type="text/javascript">
      // We don't want any conflicts
      jQuery.noConflict();
      
      // SELECT * FROM flickr.photos.search 
      // WHERE text='Athega' LIMIT 8
      var query = 'http://query.yahooapis.com/v1/public/yql?q=' + 
                  'select%20*%20from%20flickr.photos.search%20' +
                  'where%20text%3D%22Athega%22%20limit%208' +
                  '&format=json&callback=?';
      
      // Get the data
      (function($) {
        $.getJSON(query, function(yql) {
          $.each(yql.query.results.photo, 
          function(index, photo) {
            // Build the url
            photo.url = 'http://farm' + photo.farm + 
                        '.static.flickr.com/' + photo.server + 
                        '/' + photo.id + '_' + photo.secret + '_s.jpg';
            
            // Create and append the img to the #images div
            $('<img />').attr({ 
              src: photo.url, 
              title: photo.title
            }).appendTo('#images');
            
          });
        });
      })(jQuery);
    </script>
    <style type="text/css">
      #images {
        width: 300px;
      }
    </style>
  </head>
  <body>
    <div id="images"></div>
  </body>
</html>

Mer information

Introduktion till jQuery

peter / 27.feb.2009

Vad är jQuery?

Ett open source JavaScript bibliotek som förenklar interaktionen mellan HTML och JavaScript.

jQuery är byggt runt CSS selektorer (CSS 1, 2 och 3) och sedan en tid använder man motorn Sizzler för att hantera de tunga lyften.

jQuery fyllde tre år den 14:e januari, version 1.3 släpptes samma dag.

Lätt att använda

  • Helt unobtrusive
  • Använder CSS för att applicera funktionalitet
  • Lätt att separera beteende
  • Snabb, “kärnfull” syntax
“Fokus för jQuery är att hitta några element, och sedan göra något med dem

$('div').addClass('special');

Varför jQuery?

  • Väldokumenterat
  • Vältestat (1500+ tester)
  • Gratis, öppen källkod
    • GPL eller MIT (dubbellicensierad)
  • Lättviktigt
    • 19kB (Minifierad och Gzippad)
  • Massor av plugins
  • Fri hosting hos Google (vafritt)
  • Fantastisk community
  • Allt fungerar i IE 6+, FF 2+, Safari 3+, Opera 9+ samt Chrome.

Vem använder jQuery?

  • Projekt
    • Wordpress, Drupal, CakePHP, Textpattern, Mozilla
  • Företag
    • Google, IBM, Amazon, Digg, Netflix, Dell, HP, Bank of America, Intel, NBC, CBS, BBC, Reuters, Newsweek, Boston Globe, Fler..
  • Många fler…

Prestanda

Den senaste versionen (1.3.2) släpptes den 20:e februari och den innehåller ett flertal prestandaförbättringar:

Tillgänglighet

  • Tangentbord
  • Skärmläsare
  • Bidrag från Mozilla Foundation för att implementera WAI-ARIA

Kod

Plugins

jQuery är tänkt att byggas ut med hjälp av plugins.

Att lägga på nya metoder:


jQuery('div').hideRemove();

Trivialt att implementera:

1
2
3
4
5
jQuery.fn.hideRemove = function(speed) {
  return this.hide(speed, function() {
    jQuery(this).remove();
  });
};

Exempel på plugins:

  • Forms: bättre hantering av formulär
  • Dimensions: mängder av mått på webbläsarfönstret
  • UI: drag och släpp, widgets, teman
  • jQuery Google Charts: Wrapper runt Google Charts API:et

Mer information http://plugins.jquery.com/

Konflikter

Till skillnad från många andra JavaScript ramverk så är utvecklarna av jQuery måna om att inte skräpa ner i det globala namnutrymmet. Man behöver inte ens exponera $-metoden om man inte vill.

1
2
3
4
5
jQuery.noConflict();
    
jQuery(document).ready(function(){
  // Din egen kod
});

Man kan dock fortfarande använda sig av $ om man skickar in jQuery i en anonym metod.


(function($) { /* Kod som använder sig av $ */ })(jQuery)

Mer information http://docs.jquery.com/Using_jQuery_with_Other_Libraries

Exempel

jQuery() funktionen

1
2
3
4
5
jQuery('div#intro h2');
jQuery('div.section > p');
jQuery('input:radio');
    
$('div#intro h2');

jQuery kollektioner


$('div.section'); // returnerar en kollektion

Man kan göra metodanrop till kollektioner

1
2
3
4
5
$('div.section').size(); // Antal element som matchades av selektorn
    
$('div.section').each(function(div) {
  // Manipulation av div elementet
});

Manipulera hela kollektioner

De flesta jQuery metoderna opererar på alla matchade element i en kollektion.

1
2
3
4
$('div.section').addClass('highlighted');
$('img.photo').attr('src', '/default.png');
$('a.foo').html('<em>Click me now!</em>');
$('p:odd').css('background-color', '#ccc');

Hämta värden

Några metoder returnerar värdet på det först matchade elementet.

1
2
3
var height = $('div#intro').height();
var src = $('img.photo').attr('src');
var lastP = $('p:last').html();

Traversera DOM:en

jQuery tillhandahåller förbättrade metoder för att traversera DOM:en.

1
2
3
4
5
$('div.section').next();
$('div.section').prev();
$('div.section').prev('a');
$('div.section').parent();
$('div.section').parents();

Hantera events

jQuery tillhandahåller metoder för att tilldela event handlers.

1
2
3
4
$('a').click(function(ev) {
  $(this).css({backgroundColor:'orange'});
  ev.preventDefault();
});

Unobtrusive JavaScript

1
2
3
4
5
$(document).ready(function() {
  alert('The DOM is ready!');
});
    
$(function() { alert('This is a shortcut') });

Mer information http://en.wikipedia.org/wiki/Unobtrusive_JavaScript

Kedja metodanrop

Alla jQuery metoder returnerar ett nytt jQuery objekt, detta gör att man kan kedja ihop metoderna efter varandra.


$('h1').fadeOut().addClass('highlight').fadeIn();

Ajax

jQuery har bra stöd för Ajax och Ajax-liknande funktionalitet som JSONP.


$('div#intro').load('/some/file.html');

Några mer avancerade metoder:

1
2
3
4
$.get(url, params, callback);
$.post(url, params, callback);
$.getJSON(url, params, callback);
$.getScript(url, callback);

Övrigt

Microsoft och Nokia <3 jQuery

Microsoft har beslutat att skeppa stöd för jQuery i kommande versioner av Visual Studio. Detta inkluderar officiellt stöd för jQuery Intellisense.

Nokia har meddelat att de kommer att använda jQuery i sin WebKit-baserade Web Run-Time

Mer information http://blog.jquery.com/2008/09/28/jquery-microsoft-nokia/

Google AJAX Libraries

Google tillhandahåller ett CDN för ett flertal olika ramverk, jQuery är ett av dem.

Mer information http://code.google.com/apis/ajaxlibs/

Dokumentation och presentationer

API Dokumentationen för jQuery hittar man på http://api.jquery.com/ där man även kan installera en AIR-version.

John Resig’s presentation Learning jQuery @ MIT

Gott och Blandat #4

peter / 18.okt.2008

Den här gången handlar det om CSS och HTML.

CSS3 Media Queries

För ett tag sedan skulle jag använda ett stylesheet för mobila enheter genom media="handheld". Det fungerade såklart inte alls i Opera Mini 4.1, men jag tänkte inte så mycket mer på det utan löste det på annat sätt. Nu har jag tagit reda på orsaken, och den kallas CSS3 Media Queries.

Med dessa “queries” kan man definiera css-regler som appliceras baserat på vad enheten man använder sig av klarar av. I mitt exempel så har jag en regel som bara appliceras på enheter med en skärm som är mindre än 481 pixlar bred. (Av en ren händelse så har iPhone en 480px bred skärm)

1
2
3
4
5
6
7
8
9
10
11
12
@media screen and (max-width: 480px) {
  * {
    position: static !important;
    background-image: none !important;
    margin-left: 0 !important;
    padding: 0 !important;
    margin-bottom: 0 !important;
  }

 /* Resten av reglerna för mobila enheter */

}

Resultat

Opera Mini c7.se/contact
Opera Mini Demo

Opera rekomenderar dock att man även i fortsättningen använder sig av ett stylesheet med media="handheld" för de enheter som ännu inte stödjer CSS3 Media Queries.

Typografi

Enligt mig en av världens bästa webbdesigners, Dan Cederholm har skrivit en liten post om att välja den bästa tillgängliga ampersanden.

Kortfattat så går det hela ut på att lägga till en class=”amp” runt alla &-tecken.


Gott <span class="amp">&amp;</span> Blandat
1
2
3
4
span.amp {
  font-family: Baskerville, Palatino, Constantia, serif;
  font-style: italic;
}

Före

Gott & Blandat

Efter

Gott & Blandat

(Ingen skillnad? Då har din RSS-läsare troligtvis strippat bort style taggen)

För att automatisera detta kan man använda sig av Typogrify (Django) eller MarkDown+SmartyPants (Finns till de flesta publiceringssystem).

Mikroformat

Mikroformat är standarder, baserade ovanpå HTML eller XHTML. Mikroformat är en utökad semantik, som åstadkommer i (X)HTML möjligheten att märka upp information, som annars man hade behövt en annan teknik till, såsom RDF eller någon annan tillämpning av XML. Mikroformat är alltså inte en utvidgning av befintlig (X)HTML, som HTML5, utan man använder endast befintliga taggar och attribut. [Wikipedia]

Ett mikroformat jag använder mig av är hCard vilket är en 1:1 representation av vCard.

hCard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<div class="vcard" id="hcard-Peter-Hellberg">
  <img class="photo" alt="" src="http://c7.se/images/peter_small.jpg"/>
  <div class="fn n">
    <span class="given-name">Peter</span>
    <span class="family-name">Hellberg</span>
  </div>
  <div>
    <span class="role">System Developer</span>,
    <a href="http://c7.se/" class="org url">Code7 Interactive</a>
  <div>
  <h3>Email <span class="amp">&</span> Jabber</h3>
  <p>
    <a href="mailto:peter@c7.se" class="email jabber">peter@c7.se</a>
  </p>
  <h3>Address</h3>
  <div class="adr">
    <div class="street-address">Mosstenabacken 1</div>
    <div>
      <span class="postal-code">124 32</span>
      <span class="locality">Bandhagen</span> 
    </div>
    <span class="region">Stockholm</span>,
    <span class="country-name">Sweden</span>
  </div>
</div>

Med hjälp av biblioteket mofo kan jag nu hämta följande data:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
>> peter = hCard.find 'http://c7.se/contact'
=> #<HCard:0x1141e90 
 @role="System Developer", 
 @url="http://c7.se/", 
 @base_url="http://c7.se", 
 @org="Code7 Interactive", 
 @n=#<OpenStruct family_name="Hellberg", given_name="Peter">, 
 @properties=["org", "email", "fn", "url", "photo", "n", "role", "adr"],  
 @photo="http://c7.se/images/peter_small.jpg", 
 @adr=#<Adr:0x1167438 
   @country_name="Sweden", 
   @base_url="http://c7.se", 
   @region="Stockholm", 
   @properties=[
     "street_address", 
     "locality", "region", 
     "country_name", 
     "postal_code"
   ], 
   @locality="Bandhagen", 
   @postal_code="124 32", 
   @street_address="Mosstenabacken 1">, 
 @fn="Peter Hellberg", 
 @email="peter@c7.se">

Gott och Blandat #3

peter / 23.sep.2008

Forest

Spree

Spree (GitHub) är en komplett lösning för ehandel skriven i Rails. Den är distribuerad som en gem (Vilket även Axept kommer att vara när det släpps).

30 Days of Mootools 1.2 Tutorials

Precis som det låter, 30 tutorials för Mootools 1.2 hittar du på http://www.consideropen.com/blog/category/mootools-12/ (Dag 21 nu..)

Enkel tidrapportering

Jag har använt tjänsten time.onrails.org - Time tracking made simple. hela sommaren och den har verkligen levt upp till sitt namn, smidigt att lägga till nya uppdrag, sektioner (veckor/månader/etc) och framförallt att lägga in timmarna. Nu har den precis blivit ännu bättre genom att de lagt till stöd för fakturering genom Blinksale. Mitt arbetsflöde är nu att använda time.onrails.org först och sen i slutet av månaden fylla i Journyx.

For A Beautiful Web

Jag har sedan länge hållt ett öga på Andy Clarke’s privata hemsida And All That Malarkey som sedemera mynnade ut i Stuff and Nonsense. Nu har han tagit och dragit igång For A Beautiful Web som är en samling workshops med titlar som:

  • Advanced styling with CSS
  • Building design on Microformats
  • Designing web accessibility
  • Meaningful mark-up for designers

Det finns även några riktiga godbitar i den tillhörande bloggen, till exempel Time to stop showing clients static design visuals.

COLOURlovers

När jag ska färgsätta något så brukar jag för det mesta besöka colourlovers.com där det finns topplistor på färger och även hela paletter med färger som passar (mer eller mindre) bra ihop. Rekomenderas.

FamFamFam

Det händer rätt ofta att jag använder ikonerna Silk av Mark James (Twitter), enda problemet är att det är så många ikoner (1000 stycken nu) att det blir svårt att hitta rätt.

En gammal klasskompis (Twitter) har dock löst detta problem genom att utveckla FamFamFam Icon Browser

Gott och Blandat #2

peter / 22.sep.2008

Thailand 2008

Paperclip

Paperclip (GitHub) är ett plugin till ActiveRecord som gör det enkelt att använda filer som vilka andra attribut som helst. Inga extra tabeller i databasen. Det enda som krävs är att man har installerat ett bibliotek för bildbehandling.

Modell

1
2
3
4
5
class User < ActiveRecord::Base
  has_attached_file :avatar, 
                    :styles => { :medium => "300x300>",
                                 :thumb => "100x100>" }
end

Controller

1
2
3
def create
  @user = User.create( params[:user] )
end

Vyerna för Edit och New

1
2
3
form_for :user, :html => { :multipart => true } do |form|
  form.file_field :avatar
end

Vyn för Show


image_tag @user.avatar.url(:thumb)

scoped_search

scoped_search (GitHub) är en gem som gör det trivialt att söka i sina modeller utan att kräva en indexeringslösning som Thinking Sphinx.

Användning

1
2
3
class Project < ActiveRecord::Base
  searchable_on :name, :description
end

Project.search_for(params[:q]).each { |project| ... }

Gott och blandat

peter / 18.sep.2008

Nu börjar jag att skriva lite bloggposter där jag länkar till nya projekt/applikationer/kod som jag tycker verkar intressanta. Jag har valt att kalla dem “Gott och Blandat”.


Fotograf: G. Taylor McKnight

Panda

Panda (GitHub) är en Merbapplikation som hanterar uppladdning, encoding och streaming av video utvecklad av New Bamboo

Ribs

Ribs (GitHub) är ett JRuby ORM som gör det möjligt att persistera rubyobjekt med Hibernate utvecklat av Ola Bini.

Bort

Bort (GitHub) har nu släppts i version 0.2. Bort är en förkonfigurerad Railsapplikation med flera av de mest använda plugins redan installerade.

Nyheter i version 0.2

  • Uppdaterad till Rails 2.1.1
  • Role Requirement
  • Default CSS
  • Plugin Rake Task
  • Resful Authentication Site Keys

Hyperactive Resource

Hyperactive Resource (GitHub) är en utbyggnad till ActiveResource som lägger till många ActiveRecord-lika funktioner vilket underlättar för att göra “drop in” ersättningar av existerande ActiveRecord modeller. Den inkluderar dynamiska finders, validering på klientsidan, hooks vid validering och persistering samt mycket mer.

Shoulda

Shoulda (GitHub) gör det enkelt att skriva eleganta, lättförstådda och underhållningsbara test. Shoulda består av testmakron, assertions och hjälpmetoder som lagts till ramverket Test::Unit. Det är helt kompatibelt med redan existerande testfall. Bara att börja använda.

Ruby-Processing

Ruby-Processing (GitHub) är en JRuby wrapper för ramverket Processing. Viss inspiration är hämtad från NodeBox.

Dokumentation

Ny och fräsch dokumentation på http://guides.rails.info

Personnummer

peter / 07.aug.2008

Mitt första projekt paketerat som en gem är nu släppt på GitHub, det kallas “Personnummer” och inte helt oväntat hanterar det Svenska personnummer.

GemSpec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Gem::Specification.new do |s|
   s.name = "personnummer"
   s.version = "0.0.1"
   s.date = "2008-08-06"
   s.summary = "Personnummer handles validation of Swedish personal id..."
   s.description = "Personnummer handles validation of Swedish person..."
   s.has_rdoc = false
   s.email = "peter@c7.se"
   s.homepage = "http://c7.se/code/personnummer"
   s.authors = ["Peter Hellberg"]
   s.files = ["README.markdown",
                 "Changelog",
                 "LICENSE",
                 "demo.rb",
                 "lib/personnummer.rb"]
end

Installation

Lägg till GitHub i source listan (Behöver bara göras en gång)


gem sources -a http://gems.github.com

Installera, som vanligt på GitHub är namnet prefixat med användarnamn (c7)


sudo gem install c7-personnummer

Användning

1
2
3
4
5
6
7
8
9
require 'rubygems'
require 'personnummer'

p = Personnummer.new('830428-5912')

if p.valid?
  designation = (p.male?) ? 'He' : 'She'
  puts "#{designation} was born in #{p.region}"
end

Vilket kommer att returnera:


He was born in Skaraborgs län

Länkar

Prawn är ett nytt PDF bibliotek helt skrivet i Ruby. Utgångspunkterna har varit att det ska vara enkelt att producera PDF filer och att tillhandahålla all funktionalitet man behöver utan att bli begravd i komplexitet.

Funktioner som redan fungerar

  • Bounding boxes
  • Flersidiga dokument
  • Fontstorlekar
  • Inbäddade bilder
  • Justerad text
  • Kerning
  • Kurvor
  • Linjer
  • Olika sidstorlekar
  • Polygoner
  • Ruport
  • Tabeller
  • UTF-8

Exempel 1: Bildpositionering

1
2
3
4
5
6
7
8
9
10
11
12
13
Prawn::Document.generate("images.pdf", :page_layout => :landscape) do
  foo = "#{Prawn::BASEDIR}/data/images/foo.jpg"
  text "o hai"
  image foo
  text "flowing text"
  image foo, :position => :center
  text "beneath images"
  image foo, :position => :right
  text "again"
  image foo, :position => :left
  text "and again"
  image foo, :position => 50
end

Exempel 2: Dokument med olika format på respektive sida

1
2
3
4
5
6
7
8
9
Prawn::Document.generate("multi.pdf", :page_layout => :landscape) do |pdf|
   pdf.text "This is on a landscaped page"
   pdf.start_new_page(:layout => :portrait)
   pdf.text "This is on a portrait page"
   pdf.start_new_page(:size => "LEGAL")
   pdf.text "This is on legal paper size"
   pdf.start_new_page(:left_margin => 150, :right_margin => 150)
   pdf.text "This page has very wide left and right margins"
end

Installera Prawn genom RubyGems med gem install prawn eller klona från git://github.com/sandal/prawn.git

Länkar

JavaFX Preview SDK

peter / 31.jul.2008

Idag släppte SUN sin förhandsversion av JavaFX SDK’n. Jag har ända sedan Chrilles presentation på sommarkonferensen varit lite sugen på att testa JavaFX och nu finns det en komplett utvecklingsmiljö i form av Netbeans 6.1 med stöd för JavaFX att ladda ner. Java 6 krävs för att det hela ska fungera.

Exempel på syntax

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var weather1 = Weather{};

var f = Frame {
    stage: Stage {
        fill: Color.GREY
        content:[
            Group {
                transform: Transform.translate(0,5);
                content: weather1
            }
        ]
    }
    title: "Weather in Stockholm"
    closeAction: function() { System.exit(0); }
    resizable: false
    width: 255
    height: 120
    visible: true
};

Resultat

WeatherFX

JavaFXPAD

Om man bara vill leka runt lite med JavaFX så finns JavaFXPAD (Java Web Start) som är en testmiljö liknande Try Ruby! (som vi använde på en av mina genomgångar av Ruby). Man startar helt enkelt applikationen och kan skriva kod i ett textfält, koden körs direkt så man kan hela tiden se förändringar i den övre delen av fönstret.

JavaFX

Länkar

userContent.css

peter / 31.jul.2008

Adblock Plus i all ära men ibland vill man ändra själva utseendet på webbplatserna man besöker. Ett plugin som gör just detta är Greasemonkey vilket låter användaren skriva egna script för att skräddarsy sin surfning.

Jag ville dock bara lägga till lite css, detta kan man göra i filen userContent.css som under Mac OS X ska ligga i följande katalog:


~/Library/Application Support/Firefox/Profiles/[RANDOM].default/chrome/

Exempel

1
2
3
4
5
6
/* Remove ads */
iframe[name=”google_ads_frame”],
div.profile_sidebar_ads,
div.social_ad,
div#sidebar_ads,
div.rs div.sponsor { display: none !important; }

Datumväljare med MooTools

peter / 24.jul.2008

Jag behövde en datumväljare till mitt nuvarande projekt och efter lite eftersökningar så hittade jag MooTools DatePicker men den fungerade inte helt till belåtenhet. Speciellt inte med version 1.2 av MooTools så jag såg till att uppdatera den.

Det visade sig vara enklare än väntat, jag ersatte bara följande rad:


else if (dp.container) dp.container.remove();

med


else if (dp.container) dp.container.destroy();

För att göra inputfältet skrivbart (för att kunna skicka tomma datum) så tog jag bort följande rad:


dp.setProperties({'id':dp.getProperty('name'), 'readonly':true});

Resultatet

MooTools DatePicker

Länkar

Trunkerade beskrivningar i rake

peter / 22.jul.2008

Ett “problem” jag haft med senare versioner av rake (efter version 0.8) är att beskrivningarna till varje task är trunkerade till 80 tecken, oavsett hur bred terminalen faktiskt är.

Efter en snabb googling fick jag fram en stilig lösning.

lib/rake.rb


max_column = 80 - name.size - width - 7

ersätts med


max_column = cols - name.size - width - 7

och följande metoder läggs till

1
2
3
4
5
6
7
8
9
def cols
  unix? ? (%x{stty size 2>/dev/null}.split.collect { |x| x.to_i }[1]) : 80
rescue
  80
end
    
def unix?
  RUBY_PLATFORM =~ /(darwin|linux|(net|free|open)bsd|cygwin|solaris)/i
end

Länkar

nginx & thin

peter / 26.jun.2008

Jag skulle testa olika deploymentlösningar och ville testa nginx i kombination med thin även om vi antagligen kommer att köra Phusion Passenger under Apache på grund av andra system skrivna i PHP.

Jag kollade runt lite hur man skulle konfigurera nginx och hittade Nginx, my new favorite front end for mongrel cluster..

Utvecklingsversionen (0.7.3) var en aning instabil så jag valde att installera 0.6.31 och använde följande config.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
user peter peter;
worker_processes  2;

error_log  logs/error.log notice;
pid logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    # no sendfile on OSX uncomment 
    #this if your on linux or bsd
    #sendfile        on;
    tcp_nopush     on;

    keepalive_timeout  65;
    tcp_nodelay        on;

    upstream cluster {
        server 127.0.0.1:5001;
        server 127.0.0.1:5002;
    }

    gzip on;
    gzip_min_length  1100;
    gzip_buffers     4 8k;
    gzip_types       text/plain;

    server {
        listen       80;
        #server_name  localhost;
        root /path/to/public;

        access_log  off;
        rewrite_log on;

        location ~ ^/$ {
          if (-f /index.html){
            rewrite (.*) /index.html last;
          }
           proxy_pass  http://cluster;
        }

        location / {
          if (!-f $request_filename.html) {
            proxy_pass  http://cluster;
          }
          rewrite (.*) $1.html last;
        }

        location ~ .html {
           root /path/to/public;
        }

          location ~* ^.+\.(jpg|png|ico|css|zip|doc|xls|pdf|ppt|txt|js)$ {
          root /path/to/public;
        }

        location / {
            proxy_pass  http://cluster;
            proxy_redirect     off;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
    }
}

Jag blev galet imponerad av hur snabbt nginx klarar att leverera statiskt innehåll (ungefär 7400 förfrågningar/s eller 5400 Kb/s) men dynamiskt innehåll var inga problem heller, en enkel vy levererades ungefär 380-400 förfrågningar/s vid 8 samtidiga anslutningar och 2000 förfrågningar.

Det ska bli intressant att testa mephisto då den cachear rätt hårt.

Allt detta på min Macbook Pro.

Länkar

RSpec & TextMate

peter / 27.maj.2008

Genom RubyFlow fick jag reda på att version 1.1.4 av testramverket RSpec släppte idag. Jag tog tillfället i akt att börja använda det i mitt nuvarande projekt.

Det finns även integration med min editor TextMate genom projektet rspec-tmbundle.

Jag råkade dock ut för lite trubbel då jag skulle köra igång testerna, det verkade inte som om rätt version av ruby kördes. Detta avhjälptes genom att editera PATH variabeln i environment.plist så att den ruby-binär jag ville använda hittades först.


$ mate ~/.MacOSX/environment.plist

Loggade ut för att ladda om variablerna.

Jag skrev sedan följande spec för att testa så att allt fungerade som det skulle.

spec/models/company_spec.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
require File.dirname(__FILE__) + '/../spec_helper'

module CompanySpecHelper
  def valid_company_attributes
    { 
      :name => 'Testföretag',
      :org_number => '123456-1234', 
      :customer_number => 1
    }
  end
end

describe Company do
  include CompanySpecHelper

  before(:each) do
    @company = Company.new
    @company.attributes = valid_company_attributes
  end

  it "should be valid with all attributes" do
    @company.should be_valid
  end
  
  it "should not be valid without a name" do
    @company.name = nil
    @company.should_not be_valid
  end
end

Och det fungerade!

RSpec results

Prenumerera

Håll dig uppdaterad om vad jag gör på Athega genom rss!

Upp

Temat heter micro och är gjort av seaofclouds.
Det drivs med Mephisto under Ruby on Rails