<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 <title>Andrzej Sliwa</title>
 <link href="http://andrzejsliwa.github.com/atom.xml" rel="self"/>
 <updated>2010-08-03T02:35:53-07:00</updated>
 <id>http://andrzejsliwa.com/</id>
 <author>
   <name>Andrzej Sliwa</name>
   <email>andrzej.sliwa@i-tool.eu</email>
 </author>
 
 <entry>
   <id>http://andrzejsliwa.com/2010/08/02/aplikacja-django-na-gae</id>
   <link href="http://andrzejsliwa.github.com/2010/08/02/aplikacja-django-na-gae"/>
   <title>Aplikacja Django na Google App Engine - Część I (konfiguracja aplikacji i pierwsze wdrożenie)</title>
   <author>
     <name>Andrzej Sliwa</name>
     <email>andrzej.sliwa@i-tool.eu</email>
   </author>
   <content type="html">&lt;p&gt;Platforma &lt;a href=&quot;http://en.wikipedia.org/wiki/Software_as_a_service&quot;&gt;SaaS&lt;/a&gt; o nazwie &lt;a href=&quot;http://code.google.com/appengine/&quot;&gt;Google App Engine&lt;/a&gt; (w skrócie &lt;strong&gt;GAE&lt;/strong&gt;) jest wspaniałą alternatywą dla kosztownych opcji hostowania aplikacji opartych o serwery dedykowane czy konta współdzielone. Udostępnia ona całą infrastrukturę tworzenia aplikacji z wykorzystaniem języka &lt;a href=&quot;http://www.python.org/&quot;&gt;Python&lt;/a&gt; lub języków opartych o &lt;a href=&quot;http://en.wikipedia.org/wiki/Java_Virtual_Machine&quot;&gt;JVM&lt;/a&gt;. Oczywiście istnieją ograniczenia związane z architekturą &lt;strong&gt;GAE&lt;/strong&gt;, wymuszając pewne sposoby pracy z platformą (niejako wymuszając właściwe rozwiązania, również ze względu na optymalizacje kosztów)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GAE&lt;/strong&gt; udostępnia tak naprawdę standardową infrastrukturę aplikacji opartą o sprawdzone rozwiązania firmy Google. Od jakiegoś czasu istnieje również możliwość uzyskania komercyjnego wsparcia.&lt;/p&gt;

&lt;p&gt;Wykorzystując &lt;strong&gt;GAE&lt;/strong&gt; mamy możliwość skorzystania z darmowych limitów przysługujących na każdą aplikacje by wraz ze wzrostem popularności naszej aplikacji przesiąść się na komercyjne konto. Takie podejście pozwala nam również na całkowite zrzucenie odpowiedzialności i zadań związanych ze skalowaniem naszej aplikacji co jest największą zaletą tej platformy.&lt;/p&gt;

&lt;p&gt;W dzisiejszym wpisie chciałbym &quot;pokrótce&quot; przeprowadzić czytelnika przez proces uruchomienia przykładowej aplikacji bazującej na &lt;strong&gt;GAE&lt;/strong&gt; używając zmodyfikowanej wersji Django (popularnego frameworka bazującego na pythonie).&lt;/p&gt;

&lt;p&gt;Standardowa wersja &lt;a href=&quot;http://www.djangoproject.com&quot;&gt;Django&lt;/a&gt; (obecna wersja &lt;strong&gt;1.2&lt;/strong&gt;) nie posiada jeszcze wsparcia dla nierelacyjnych baz danych takich jak &lt;a href=&quot;http://en.wikipedia.org/wiki/BigTable&quot;&gt;BigTable&lt;/a&gt; czy &lt;a href=&quot;http://www.mongodb.org/&quot;&gt;MongoDB&lt;/a&gt;. Na szczęście dzięki pracy panów z &lt;a href=&quot;http://www.allbuttonspressed.com/projects/django-nonrel&quot;&gt;All Buttons Pressed&lt;/a&gt; mamy możliwość wykorzystania zmodyfikowanej wersji &lt;strong&gt;Django&lt;/strong&gt;, która zawiera odpowiednie backendy wspierające w/w bazy danych.&lt;/p&gt;

&lt;p&gt;Pierwszą czynnością którą, musimy wykonać (&lt;a href=&quot;http://code.google.com/appengine/downloads.html&quot;&gt;zaraz po zainstalowaniu GAE na swoim systemie&lt;/a&gt;) celem stworzenia aplikacji bazującej na &lt;strong&gt;GAE&lt;/strong&gt;,
jest zalogowanie się na stronie &lt;a href=&quot;http://code.google.com/appengine/&quot;&gt;Google App Engine&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-registration.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;Podstawową zaletą korzystania z usług Google jest użycie tego samego konta do wielu usług
w tym również do &lt;strong&gt;GAE&lt;/strong&gt;. W tym celu wprowadzamy nazwę użytkownika i logujemy się:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-signup.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;Zaraz po zalogowaniu widzimy zaproszenie do rejestracji nowej aplikacji (w przypadku późniejszego logowania w tym miejscu pojawi się również list naszych aplikacji). Obecnie limit własnych aplikacji wynosi 10 i nie obejmuje aplikacji udostępnionych nam przez inne osoby.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-new-app.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;W przypadku pierwszej rejestracji aplikacji wymagana jest aktywacja poprzez SMS:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-activation.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;której dokonujemy wprowadzając kod aktywacyjny przesłany na naszą komórkę:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-activation-2.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;Po poprawnej aktywacji przechodzimy do rejestracji aplikacji wpisując unikalną nazwę naszej aplikacji, dokonując dodatkowych ustawień oraz akceptując regulamin usługi.&lt;/p&gt;

&lt;p&gt;Jak widać na obrazku rejestrowana aplikacja będzie dostępna pod adresem &lt;a href=&quot;http://officeshoppinglist.appspot.com&quot;&gt;officeshoppinglist.appspot.com&lt;/a&gt; zaraz po wgraniu pierwszej wersji kodu.
Istnieje możliwość podpięcia naszej aplikacji pod własny adres URL lecz istnieje ograniczenie pozwalające na podpięcie tylko jako poddomeny np.:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;http://www.mojadomena.pl&lt;/strong&gt;  (zamiast &lt;strong&gt;http://mojadomena.pl&lt;/strong&gt;)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-creating-app.png&quot;&gt;&lt;/img&gt;
&lt;img src=&quot;/images/gae-creating-app-2.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;Następnie powinniśmy zobaczyć informacje o prawidłowo zarejestrowanej aplikacji:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-creating-app-3.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;Po przejściu na dashboard powinniśmy uzyskać dostęp do podstawowych opcji konfiguracyjnych naszej aplikacji jak również zarządzania i podglądu stanu:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-dashboard.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;Kolejnym krokiem po zarejestrowaniu naszej aplikacji będzie stworzenie repozytorium (w tym przypadku repozytorium &lt;strong&gt;GIT&lt;/strong&gt;, na &lt;a href=&quot;http://github.com&quot;&gt;github.com&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-new-github-repo.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;Zgodnie z tymi instrukcjami przygotujemy nasz pusty projekt:
&lt;img src=&quot;/images/gae-new-github-repo-2.png&quot;&gt;&lt;/img&gt;
&lt;img src=&quot;/images/gae-new-github-repo-3.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;A więc...&lt;/p&gt;

&lt;p&gt;tworzymy katalog:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;mkdir officeshoppinglist
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;tworzymy pusty plik:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;officeshoppinglist
~/gae/officeshoppinglist&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;touch .gitignore
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;inicjujemy repozytorium GIT'a:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git init
Initialized empty Git repository in /Users/andrzejsliwa/gae/officeshoppinglist/.git/
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;dodajemy nasz pusty plik:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add .
~/gae/officeshoppinglist&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit -m &lt;span class=&quot;s2&quot;&gt;&amp;quot;initial commit.&amp;quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;root-commit&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; d142cc5&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; initial commit.
 0 files changed, 0 insertions&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;+&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 0 deletions&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;-&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 create mode 100644 .gitignore
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;podpinamy zdalne repozytorium oraz wysyłamy je w obecnym stanie na serwer:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git remote add origin git@github.com:andrzejsliwa/officeshoppinglist.git
~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git push origin master
Counting objects: 3, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
Writing objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3/3&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 219 bytes, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
Total 3 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, reused 0 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
To git@github.com:andrzejsliwa/officeshoppinglist.git
 * &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;new branch&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;      master -&amp;gt; master
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Wynikiem naszych działań powinno być dostępne repozytorium:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-new-github-repo-4.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;W tym momencie możemy przystąpić do konfigurowania naszego projektu. W tym celu pobieramy niezbędne zależności w formie repozytoriów mercuriala.&lt;/p&gt;

&lt;p&gt;Pobieramy zmodyfikowaną wersję Django 1.2 która wspiera nierelacyjne bazy danych (w tym przypadku BigTable):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ..
~/gae&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;hg clone http://bitbucket.org/wkornewald/django-nonrel
destination directory: django-nonrel
requesting all changes
adding changesets
adding manifests
adding file changes
added 8537 changesets with 21389 changes to 2919 files
updating to branch default
2266 files updated, 0 files merged, 0 files removed, 0 files unresolved
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;oraz dodatkowe wymagane repozytoria:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;hg clone http://bitbucket.org/wkornewald/djangoappengine
destination directory: djangoappengine
requesting all changes
adding changesets
adding manifests
adding file changes
added 98 changesets with 194 changes to 47 files
updating to branch default
34 files updated, 0 files merged, 0 files removed, 0 files unresolved

~/gae&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;hg clone http://bitbucket.org/wkornewald/djangotoolbox
destination directory: djangotoolbox
requesting all changes
adding changesets
adding manifests
adding file changes
added 40 changesets with 86 changes to 46 files
updating to branch default
23 files updated, 0 files merged, 0 files removed, 0 files unresolved
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;W tym momencie możemy podlinkować nasze zależności do projektu za pomocą linków symbolicznych:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;ln -s ~/gae/django-nonrel/django officeshoppinglist/django
ln -s ~/gae/djangoappengine/ officeshoppinglist/djangoappengine
ln -s ~/gae/djangotoolbox/djangotoolbox officeshoppinglist/djangotoolbox
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie wracamy do naszego projektu i dodajemy reguły ignorowania do naszego pliku .gitignore:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;officeshoppinglist
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;.DS_Store
*.pyc
*.swp
djangoappengine
djangotoolbox
django
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Tworzymy plik &lt;strong&gt;app.yml&lt;/strong&gt;, gdzie wpis application musi się zgadzać z nazwą zarejestrowanej aplikacji:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;yaml&quot;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;officeshoppinglist&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;runtime&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;python&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;api_version&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;l-Scalar-Plain&quot;&gt;default_expiration&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;365d&amp;#39;&lt;/span&gt;

&lt;span class=&quot;l-Scalar-Plain&quot;&gt;handlers&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/remote_api&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;$PYTHON_LIB/google/appengine/ext/remote_api/handler.py&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;admin&lt;/span&gt;

&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/_ah/queue/deferred&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;djangoappengine/deferred/handler.py&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;admin&lt;/span&gt;

&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/media/admin&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;static_dir&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;django/contrib/admin/media&lt;/span&gt;

&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/media&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;static_dir&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;media&lt;/span&gt;

&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/robots.txt&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;static_files&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;robots.txt&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;robots.txt&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;secure&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;optional&lt;/span&gt;

&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/.*&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;djangoappengine/main/main.py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Kolejno tworzymy: plik &lt;strong&gt;cron.yml&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;yaml&quot;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;cron&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;keep alive&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;schedule&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;every 2 minutes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;plik &lt;strong&gt;index.yaml&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;yaml&quot;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;indexes&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;

&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;django_admin_log&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;user_id&lt;/span&gt;
  &lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;action_time&lt;/span&gt;
    &lt;span class=&quot;l-Scalar-Plain&quot;&gt;direction&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;desc&lt;/span&gt;

&lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;django_content_type&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;app_label&lt;/span&gt;
  &lt;span class=&quot;p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;name&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# AUTOGENERATED&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# This index.yaml is automatically updated whenever the dev_appserver&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# detects that a new type of query is run.  If you want to manage the&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# index.yaml file manually, remove the above marker line (the line&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# saying &amp;quot;# AUTOGENERATED&amp;quot;).  If you want to manage some indexes&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# manually, move them above the marker line.  The index.yaml file is&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# automatically uploaded to the admin console when you next deploy&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# your application using appcfg.py.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;plik &lt;strong&gt;robots.txt&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;yaml&quot;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;User-agent&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;Disallow&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;plik &lt;strong&gt;manage.py&lt;/strong&gt; (oraz dodajemy mu prawa do wykonania):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env python&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Add &amp;quot;common-apps&amp;quot; folder to sys.path if it exists&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;common_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;common-apps&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;common_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;common_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Initialize App Engine SDK if djangoappengine backend is installed&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;djangoappengine.boot&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup_env&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;setup_env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;django.core.management&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute_manager&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;settings&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# Assumed to be in the same directory.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Error: Can&amp;#39;t find the file &amp;#39;settings.py&amp;#39; in the directory containing &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%r&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;. It appears you&amp;#39;ve customi&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;execute_manager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;chmod +x manage.py
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;plik &lt;strong&gt;urls.py&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;django.conf.urls.defaults&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Uncomment the next two lines to enable the admin&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;django.contrib&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;admin&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;urlpatterns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;patterns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Uncomment the next line to enable the admin:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;r&amp;#39;^admin/&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;admin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;plik &lt;strong&gt;settings.py&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;djangoappengine.settings_base&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;has_djangoappengine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;has_djangoappengine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DEBUG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;TEMPLATE_DEBUG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DEBUG&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;SECRET_KEY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;!6r1e$z801cxu#d#rcgsnpvw0g#bn62nqz10#-ci+qlvalaf&amp;amp;1&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;djangotoolbox&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.admin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.auth&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.sessions&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.contenttypes&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;has_djangoappengine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;djangoappengine&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INSTALLED_APPS&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ADMIN_MEDIA_PREFIX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;/media/admin/&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MEDIA_ROOT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;media&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;TEMPLATE_DIRS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;templates&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ROOT_URLCONF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;urls&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;oraz bardzo ważny pusty plik &lt;strong&gt;init&lt;/strong&gt;.py:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;touch __init__.py
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Tworzymy pliki szablonów i standardowych błędów zgodne z systemem django &lt;a href=&quot;http://github.com/andrzejsliwa/officeshoppinglist/tree/master/templates/&quot;&gt;http://github.com/andrzejsliwa/officeshoppinglist/tree/master/templates/&lt;/a&gt;.
Wynikiem naszych działań powinna być taka oto struktura projektu:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master*&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;tree
.
|-- __init__.py
|-- __init__.pyc
|-- app.yaml
|-- cron.yaml
|-- django -&amp;gt; /Users/andrzejsliwa/gae/django-nonrel/django
|-- djangoappengine -&amp;gt; /Users/andrzejsliwa/gae/djangoappengine/
|-- djangotoolbox -&amp;gt; /Users/andrzejsliwa/gae/djangotoolbox/djangotoolbox
|-- index.yaml
|-- manage.py
|-- robots.txt
|-- settings.py
|-- settings.pyc
|-- templates
|   |-- 404.html
|   |-- 500.html
|   &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;-- base.html
|-- urls.py
&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;-- urls.pyc

4 directories, 14 files
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;W tym momencie jesteśmy gotowi do testowego uruchomienia naszej aplikacji za pomocą polecenia:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./manage.py runserver
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Po otwarciu aplikacji pod adresem http://localhost:8000 powinniśmy zobaczyć:
&lt;img src=&quot;/images/gae-firstrun.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;oraz taki output w konsoli:
&lt;img src=&quot;/images/gae-terminal-first-run.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;W tym momencie możemy uruchomić wdrożenie naszej aplikacji na serwer produkcyjny:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;./manage.py deploy
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Wynikiem tego polecenia (które pyta o dane logowania by nas uwierzytelnić) jest:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;./manage.py deploy
Application: officeshoppinglist; version: 1.
Server: appengine.google.com.
Scanning files on &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;disk.
Scanned 500 files.
Scanned 1000 files.
Initiating update.
Email: sliwa.andrzej@gmail.com
Password &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;sliwa.andrzej@gmail.com:
Cloning 79 static files.
Cloning 1266 application files.
Cloned 100 files.
Cloned 200 files.
Cloned 300 files.
Cloned 400 files.
Cloned 500 files.
Cloned 600 files.
Cloned 700 files.
Cloned 800 files.
Cloned 900 files.
Cloned 1000 files.
Cloned 1100 files.
Cloned 1200 files.
Deploying new version.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Will check again in 1 seconds.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Will check again in 2 seconds.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Will check again in 4 seconds.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Will check again in 8 seconds.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Will check again in 16 seconds.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Closing update: new version is ready to start serving.
Uploading index definitions.
Uploading cron entries.
Running syncdb.
Login via Google Account:sliwa.andrzej@gmail.com
Password:
Traceback &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;most recent call last&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;./manage.py&amp;quot;&lt;/span&gt;, line 26, in &amp;lt;module&amp;gt;
    execute_manager&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;settings&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/django/core/management/__init__.py&amp;quot;&lt;/span&gt;, line 438, in execute_manager
    utility.execute&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/django/core/management/__init__.py&amp;quot;&lt;/span&gt;, line 379, in execute
    self.fetch_command&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;subcommand&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.run_from_argv&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;self.argv&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/djangoappengine/management/commands/deploy.py&amp;quot;&lt;/span&gt;, line 72, in run_from_argv
    run_appcfg&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;argv&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/djangoappengine/management/commands/deploy.py&amp;quot;&lt;/span&gt;, line 53, in run_appcfg
    call_command&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;syncdb&amp;#39;&lt;/span&gt;, &lt;span class=&quot;nv&quot;&gt;remote&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;True, &lt;span class=&quot;nv&quot;&gt;interactive&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;True&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/django/core/management/__init__.py&amp;quot;&lt;/span&gt;, line 166, in call_command
    &lt;span class=&quot;k&quot;&gt;return &lt;/span&gt;klass.execute&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;*args, **defaults&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/django/core/management/base.py&amp;quot;&lt;/span&gt;, line 218, in execute
    &lt;span class=&quot;nv&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; self.handle&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;*args, **options&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/django/core/management/base.py&amp;quot;&lt;/span&gt;, line 347, in handle
    &lt;span class=&quot;k&quot;&gt;return &lt;/span&gt;self.handle_noargs&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;**options&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/django/core/management/commands/syncdb.py&amp;quot;&lt;/span&gt;, line 103, in handle_noargs
    emit_post_sync_signal&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;created_models, verbosity, interactive, db&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/django/core/management/sql.py&amp;quot;&lt;/span&gt;, line 185, in emit_post_sync_signal
    &lt;span class=&quot;nv&quot;&gt;interactive&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;interactive, &lt;span class=&quot;nv&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;db&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/django/dispatch/dispatcher.py&amp;quot;&lt;/span&gt;, line 162, in send
    &lt;span class=&quot;nv&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; receiver&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;signal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;self, &lt;span class=&quot;nv&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;sender, **named&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/django/contrib/contenttypes/management.py&amp;quot;&lt;/span&gt;, line 11, in update_contenttypes
    &lt;span class=&quot;nv&quot;&gt;content_types&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; list&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ContentType.objects.filter&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;app_label&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;app.__name__.split&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)[&lt;/span&gt;-2&lt;span class=&quot;o&quot;&gt;]))&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/django/db/models/query.py&amp;quot;&lt;/span&gt;, line 83, in __len__
    self._result_cache.extend&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;list&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;self._iter&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/django/db/models/query.py&amp;quot;&lt;/span&gt;, line 269, in iterator
    &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;row in compiler.results_iter&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;:
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/djangotoolbox/db/basecompiler.py&amp;quot;&lt;/span&gt;, line 219, in results_iter
    &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;entity in self.build_query&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;fields&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.fetch&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;low_mark, high_mark&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Users/andrzejsliwa/gae/officeshoppinglist/djangoappengine/db/compiler.py&amp;quot;&lt;/span&gt;, line 95, in fetch
    &lt;span class=&quot;nv&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; query.Run&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;**kw&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/datastore.py&amp;quot;&lt;/span&gt;, line 1148, in Run
    &lt;span class=&quot;k&quot;&gt;return &lt;/span&gt;self._Run&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;**kwargs&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;s2&quot;&gt;&amp;quot;/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/datastore.py&amp;quot;&lt;/span&gt;, line 1185, in _Run
    str&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;exc&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; + &lt;span class=&quot;s1&quot;&gt;&amp;#39;\nThis query needs this index:\n&amp;#39;&lt;/span&gt; + yaml&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
google.appengine.api.datastore_errors.NeedIndexError: The index &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;this query is not ready to serve. See the Datastore Indexes page in the Admin Console.
This query needs this index:
- kind: django_content_type
  properties:
  - name: app_label
  - name: name
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Wyjątek w tym miejscu jest czymś normalnym ze względu na to że indeksy potrzebują czasu na zbudowanie co
możemy potwierdzić obserwując nasz &lt;a href=&quot;https://appengine.google.com/&quot;&gt;dashboard&lt;/a&gt; w sekcji Datastore Indexes:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-indexes.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;Po poprawnym wdrożeniu powinniśmy zobaczyć taki oto wynik (wprowadzenia adresu: &lt;a href=&quot;http://officeshoppinglist.appspot.com/admin/&quot;&gt;http://officeshoppinglist.appspot.com/admin/&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-remote-admin.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;oraz taki wynik (wprowadzenia adresu: &lt;a href=&quot;http://officeshoppinglist.appspot.com/&quot;&gt;http://officeshoppinglist.appspot.com/&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/gae-remote.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;

&lt;p&gt;Po zbudowaniu indeksów kolejne wdrożenie odbędzie się już bez błędów:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master*&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./manage.py deploy
Application: officeshoppinglist; version: 1.
Server: appengine.google.com.
Scanning files on &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;disk.
Scanned 500 files.
Scanned 1000 files.
Initiating update.
Email: sliwa.andrzej@gmail.com
Password &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;sliwa.andrzej@gmail.com:
Cloning 79 static files.
Cloning 1266 application files.
Cloned 100 files.
Cloned 200 files.
Cloned 300 files.
Cloned 400 files.
Cloned 500 files.
Cloned 600 files.
Cloned 700 files.
Cloned 800 files.
Cloned 900 files.
Cloned 1000 files.
Cloned 1100 files.
Cloned 1200 files.
Uploading 1 files and blobs.
Uploaded 1 files and blobs
Deploying new version.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Will check again in 1 seconds.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Will check again in 2 seconds.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Will check again in 4 seconds.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Will check again in 8 seconds.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Will check again in 16 seconds.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Will check again in 32 seconds.
Checking &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;new version is ready to serve.
Closing update: new version is ready to start serving.
Uploading index definitions.
Uploading cron entries.
Running syncdb.
Login via Google Account:sliwa.andrzej@gmail.com
Password:
No fixtures found.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Polecam również przyjrzeć się bliżej dostępnym poleceniom &lt;strong&gt;manage.py&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master*&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./manage.py
Usage: manage.py subcommand &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;options&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;args&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

Options:
  -v VERBOSITY, --verbosity&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;VERBOSITY
                        Verbosity level; &lt;span class=&quot;nv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;minimal output, &lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;normal output,
                        &lt;span class=&quot;nv&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;all output
  --settings&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;SETTINGS   The Python path to a settings module, e.g.
                        &lt;span class=&quot;s2&quot;&gt;&amp;quot;myproject.settings.main&amp;quot;&lt;/span&gt;. If this isn&lt;span class=&quot;s1&quot;&gt;&amp;#39;t provided, the&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;                        DJANGO_SETTINGS_MODULE environment variable will be&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;                        used.&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;  --pythonpath=PYTHONPATH&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;                        A directory to add to the Python path, e.g.&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;                        &amp;quot;/home/djangoprojects/myproject&amp;quot;.&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;  --traceback           Print traceback on exception&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;  --version             show program&amp;#39;&lt;/span&gt;s version number and &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;
  -h, --help            show this &lt;span class=&quot;nb&quot;&gt;help &lt;/span&gt;message and &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;

Type &lt;span class=&quot;s1&quot;&gt;&amp;#39;manage.py help &amp;lt;subcommand&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;help &lt;/span&gt;on a specific subcommand.

Available subcommands:
  changepassword
  cleanup
  compilemessages
  createcachetable
  createsuperuser
  dbshell
  deploy
  diffsettings
  dumpdata
  flush
  inspectdb
  loaddata
  makemessages
  remote
  reset
  runfcgi
  runserver
  shell
  sql
  sqlall
  sqlclear
  sqlcustom
  sqlflush
  sqlindexes
  sqlinitialdata
  sqlreset
  sqlsequencereset
  startapp
  syncdb
  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;  &lt;/span&gt;testserver
  validate
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Szczególnie poleceniu &lt;strong&gt;remote&lt;/strong&gt;, które pozwala nam na wykonywanie pozostałych poleceń na zdalnym wdrożonym systemie:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master*&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./manage.py remote syncdb
INFO     2010-08-02 07:44:17,050 base.py:154&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Setting up remote_api &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;officeshoppinglist&amp;quot;&lt;/span&gt; at http://officeshoppinglist.appspot.com/remote_api
INFO     2010-08-02 07:44:17,061 appengine_rpc.py:159&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Server: officeshoppinglist.appspot.com
INFO     2010-08-02 07:44:17,061 base.py:162&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Now using the remote datastore &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;officeshoppinglist&amp;quot;&lt;/span&gt; at http://officeshoppinglist.appspot.com/remote_api
Login via Google Account:sliwa.andrzej@gmail.com
Password:
No fixtures found.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master*&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./manage.py remote shell
INFO     2010-08-02 07:45:52,392 base.py:154&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Setting up remote_api &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;officeshoppinglist&amp;quot;&lt;/span&gt; at http://officeshoppinglist.appspot.com/remote_api
INFO     2010-08-02 07:45:52,405 appengine_rpc.py:159&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Server: officeshoppinglist.appspot.com
INFO     2010-08-02 07:45:52,407 base.py:162&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Now using the remote datastore &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;officeshoppinglist&amp;quot;&lt;/span&gt; at http://officeshoppinglist.appspot.com/remote_api
Python 2.5.5 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;r255:77872, Jun 12 2010, 00:13:50&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;GCC 4.2.1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Apple Inc. build 5659&lt;span class=&quot;o&quot;&gt;)]&lt;/span&gt; on darwin
Type &lt;span class=&quot;s2&quot;&gt;&amp;quot;help&amp;quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;copyright&amp;quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&amp;quot;credits&amp;quot;&lt;/span&gt; or &lt;span class=&quot;s2&quot;&gt;&amp;quot;license&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;more information.
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;InteractiveConsole&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&amp;gt;&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Na koniec dodajemy wszystkie pliki do repozytorium i wypycham je na zdalny serwer &lt;strong&gt;GIT'a&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master*&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add .
~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master*&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit -m &lt;span class=&quot;s2&quot;&gt;&amp;quot;initial import.&amp;quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master c6b310e&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; initial import.
 11 files changed, 186 insertions&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;+&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 0 deletions&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;-&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 create mode 100644 __init__.py
 create mode 100644 app.yaml
 create mode 100644 cron.yaml
 create mode 100644 index.yaml
 create mode 100755 manage.py
 create mode 100644 robots.txt
 create mode 100644 settings.py
 create mode 100644 templates/404.html
 create mode 100644 templates/500.html
 create mode 100644 templates/base.html
 create mode 100644 urls.py

~/gae/officeshoppinglist&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git push
Counting objects: 16, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
Delta compression using up to 2 threads.
Compressing objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;13/13&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
Writing objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;14/14&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 3.16 KiB, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
Total 14 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, reused 0 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
To git@github.com:andrzejsliwa/officeshoppinglist.git
   d142cc5..c6b310e  master -&amp;gt; master
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Aktualny kod:
&lt;a href=&quot;http://github.com/andrzejsliwa/officeshoppinglist&quot;&gt;http://github.com/andrzejsliwa/officeshoppinglist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lektura obowiązkowa:
&lt;a href=&quot;http://www.allbuttonspressed.com/projects/django-nonrel&quot;&gt;http://www.allbuttonspressed.com/projects/django-nonrel&lt;/a&gt;
&lt;a href=&quot;http://www.allbuttonspressed.com/blog/django/2010/01/Native-Django-on-App-Engine&quot;&gt;http://www.allbuttonspressed.com/blog/django/2010/01/Native-Django-on-App-Engine&lt;/a&gt;
&lt;a href=&quot;http://arrogantprogrammer.blogspot.com/2010/03/django-nonrel-and-google-app-engine.html&quot;&gt;http://arrogantprogrammer.blogspot.com/2010/03/django-nonrel-and-google-app-engine.html&lt;/a&gt;
&lt;a href=&quot;http://css.dzone.com/articles/django-nonrel-picking-momentum&quot;&gt;http://css.dzone.com/articles/django-nonrel-picking-momentum&lt;/a&gt;
&lt;a href=&quot;http://docs.djangoproject.com/en/1.2/&quot;&gt;http://docs.djangoproject.com/en/1.2/&lt;/a&gt;
&lt;a href=&quot;http://code.google.com/appengine/docs/python/overview.html&quot;&gt;http://code.google.com/appengine/docs/python/overview.html&lt;/a&gt;&lt;/p&gt;
</content>
   <updated>2010-08-02T00:00:00-07:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="django" label="django" />
   <updated>2010-08-02T00:00:00-07:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="gae" label="gae" />
 </entry>
 
 <entry>
   <id>http://andrzejsliwa.com/2010/05/04/prezentacja-git</id>
   <link href="http://andrzejsliwa.github.com/2010/05/04/prezentacja-git"/>
   <title>Prezentacja GIT</title>
   <author>
     <name>Andrzej Sliwa</name>
     <email>andrzej.sliwa@i-tool.eu</email>
   </author>
   <content type="html">&lt;p&gt;W ubiegłym roku miałem przyjemność popełnić prezentacje na temat &lt;a href=&quot;http://git-scm.com/&quot;&gt;GIT&lt;/a&gt;, na konferencji &lt;a href=&quot;http://java4people.com/&quot;&gt;Java4People&lt;/a&gt;. Dzisiaj znalazłem dzięki uprzejmości kolegi nagranie tej prezentacji:&lt;/p&gt;

&lt;div style=&quot;background: black;-moz-border-radius: 0.3em;
  -webkit-border-radius: 0.3em;&quot;&gt;
&lt;p style=&quot;margin-left: 8px;&quot;&gt;
&lt;object width=&quot;740&quot; height=&quot;490&quot;&gt;
  &lt;param name=&quot;movie&quot; value=&quot;http://www.parleys.com/share/parleysshare2.swf?pageId=1890&quot;/&gt;
  &lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;/&gt;
  &lt;param name=&quot;pageId&quot; value=&quot;1890&quot;/&gt;
  &lt;embed src=&quot;http://www.parleys.com/share/parleysshare2.swf?pageId=1890&quot; type=&quot;application/x-shockwave-flash&quot; allowfullscreen=&quot;true&quot; width=&quot;740&quot; height=&quot;490&quot;/&gt;
&lt;/object&gt;
&lt;/p&gt;
&lt;/div&gt;


&lt;p&gt;W razie problemów z odtwarzaniem polecam link bezpośredni: &lt;a href=&quot;http://parleys.com/#st=5&amp;amp;sl=3&amp;amp;id=1890&quot;&gt;Prezentacja GIT&lt;/a&gt;&lt;/p&gt;
</content>
   <updated>2010-05-04T00:00:00-07:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="git" label="git" />
 </entry>
 
 <entry>
   <id>http://andrzejsliwa.com/2010/03/01/cucumber-obsluga-kilku-sesji</id>
   <link href="http://andrzejsliwa.github.com/2010/03/01/cucumber-obsluga-kilku-sesji"/>
   <title>Cucumber - obsługa kilku sesji</title>
   <author>
     <name>Andrzej Sliwa</name>
     <email>andrzej.sliwa@i-tool.eu</email>
   </author>
   <content type="html">&lt;p&gt;Większość standardowych zadań związanych z testowaniem aplikacji jest w prosty sposób do zrealizowania z użyciem domyślnych kroków Cucumbera. Z założenia &lt;a href=&quot;http://cukes.info/&quot;&gt;Cucumber&lt;/a&gt; służy do testów funkcjonalnych, lecz można go również zastosować do realizacji &quot;testów&quot; integracyjnych. Chodzi mi o taką sytuację kiedy chcemy przetestować w jednym scenariuszu interakcje pomiędzy działaniami kilku użytkowników, szczególnie gdy z jakiś powodów nie możemy używać ponownego wylogowania i zalogowania, gdyż wpływa ono w jakiś sposób na stan aplikacji. Na ten problem zwrócił mi uwagę mój kolega &lt;a href=&quot;http://niczsoft.com&quot;&gt;Michał Papis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;W przypadku standardowych wbudowanych mechanizmów testowania możemy skorzystać z bloku
&lt;strong&gt;open_session&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;open_session&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CustomDsl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;https!&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/login&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:username&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;password&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assert_equal&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/welcome&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;https!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Lecz w przypadku cucumbera, który opiera się o poszczególne definicje kroków konieczne jest znalezienie rozwiązania pasującego do formy w jakiej tworzone są scenariusze.&lt;/p&gt;

&lt;p&gt;W tym celu przygotowałem taki oto plik kroków (&lt;strong&gt;mizzeria_steps.rb&lt;/strong&gt;):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ActionController&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Integration&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Session&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;switch_session_by_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@sessions_by_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nil?&lt;/span&gt;
          &lt;span class=&quot;vi&quot;&gt;@sessions_by_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clone&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@sessions_by_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@sessions_by_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clone&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@sessions_by_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_sym&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;Given&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /^session name is &amp;quot;([^\&amp;quot;]*)&amp;quot;$/&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;switch_session_by_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Użycie tego mechanizmu (multiple session) jest trywialnie proste, wykonujemy następujący krok:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;cucumber&quot;&gt;&lt;span class=&quot;k&quot;&gt;Given &lt;/span&gt;session name is &lt;span class=&quot;s&quot;&gt;&amp;quot;new user&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;W tym przypadku tworzona jest &lt;strong&gt;nazwana&lt;/strong&gt; sesja która jest nie zależna od innych (również od domyślnej). Dostęp do domyślnej nazwanej sesji odbywa się poprzez użycie nazwy: &lt;strong&gt;default&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;cucumber&quot;&gt;&lt;span class=&quot;k&quot;&gt;Given &lt;/span&gt;session name is &lt;span class=&quot;s&quot;&gt;&amp;quot;default&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Jak to mówią małe proste i funkcjonalne rozwiązanie, a cieszy :)&lt;/p&gt;

&lt;p&gt;Lektura obowiązkowa:
&lt;a href=&quot;http://guides.rubyonrails.org/testing.html#integration-testing-examples&quot;&gt;http://guides.rubyonrails.org/testing.html#integration-testing-examples&lt;/a&gt;&lt;/p&gt;
</content>
   <updated>2010-03-01T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="rubyonrails" label="rubyonrails" />
   <updated>2010-03-01T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="cucumber" label="cucumber" />
 </entry>
 
 <entry>
   <id>http://andrzejsliwa.com/2010/02/26/rails-3-od-zera-cz-1</id>
   <link href="http://andrzejsliwa.github.com/2010/02/26/rails-3-od-zera-cz-1"/>
   <title>Rails 3 od zera ... (część 1.)</title>
   <author>
     <name>Andrzej Sliwa</name>
     <email>andrzej.sliwa@i-tool.eu</email>
   </author>
   <content type="html">&lt;p&gt;Framework Ruby on Rails doczekał się w końcu wersji 3, czas więc na pierwszą &quot;szpachle&quot; ;)&lt;/p&gt;

&lt;p&gt;Pierwszą niezbędną wg mnie rzeczą jaką będziemy potrzebować jest &lt;a href=&quot;http://rvm.beginrescueend.com/&quot;&gt;RVM&lt;/a&gt; (Ruby Version Manager), który
znacznie ułatwia zarówno eksperymenty, testowanie jak codzienną pracę. RVM pozwala na instalacje kilku wersji interpretera Ruby oraz sprawne i szybkie przełaczanie między nimi. Największą jego zaletą jest również fakt instalacji interpreterów w katalogu użytkownika, eliminując konieczność posiadania uprawnień do instalacji oprogramowania i używania polecenia sudo&lt;/p&gt;

&lt;p&gt;Proponuje zainstalować go bezpośrednio ze źródeł, odcinając tym samym pępowine od &lt;strong&gt;systemowej instalacji języka Ruby&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;Last login: Fri Feb 26 18:29:46 on ttys004
mkdir -p ~/.rvm/src/ &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/.rvm/src &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; rm -rf ./rvm/ &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; git clone git://github.com/wayneeseguin/rvm.git &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;rvm &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./install
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie dodajemy niezbędno linijkę do pliku ~/.profile:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; -s /Users/andrzejsliwa/.rvm/scripts/rvm &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; ; &lt;span class=&quot;k&quot;&gt;then &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; /Users/andrzejsliwa/.rvm/scripts/rvm ; &lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;     
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;W tym momencie musimy uruchomić nową sesję terminala tak by dodane przez nas zmiany odniosły skutek.
Poprawną instalację powinnień potwierdzić taki oto rezultat polecenia &lt;strong&gt;rvm list&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rvm list

rvm Rubies

System Ruby

   system &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; x86_64 i386 ppc &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rvm install 1.9.1

Installing Ruby from &lt;span class=&quot;nb&quot;&gt;source &lt;/span&gt;to: /Users/andrzejsliwa/.rvm/rubies/ruby-1.9.1-p378
Downloading ruby-1.9.1-p378, this may take a &lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;depending on your connection...

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 8862k  100 8862k    0     0   100k      0  0:01:28  0:01:28 --:--:--  121k

Extracting ruby-1.9.1-p378 ...
Configuring ruby-1.9.1-p378, this may take a &lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;depending on your cpu&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;...
Compiling ruby-1.9.1-p378, this may take a &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;, depending on your cpu&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;...
Installing ruby-1.9.1-p378
Installation of ruby-1.9.1-p378 is complete.
Updating rubygems &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;ruby-1.9.1-p378
Installing gems &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;ruby-1.9.1-p378.
Installing rake
Installation of gems &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;ruby-1.9.1-p378 is complete.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie instalujemy interpreter &lt;strong&gt;Rubego 1.9.1&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rvm 1.9.1 --default
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Poprawność instalacji możemy zweryfikować w następujący sposób:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;which ruby
/Users/andrzejsliwa/.rvm/rubies/ruby-1.9.1-p378/bin/ruby

mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;which gem
/Users/andrzejsliwa/.rvm/rubies/ruby-1.9.1-p378/bin/gem

mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ruby -v 
ruby 1.9.1p378 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2010-01-10 revision 26273&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;i386-darwin10.2.0&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;gem -v
1.3.6
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Chciałbym wyraźnie w tym miejscu przypomnieć że począwszy od wersji 1.3.6 &lt;strong&gt;RubyGems&lt;/strong&gt;, domyślnym źródłem gemów jest strona &lt;a href=&quot;http://rubygems.org/&quot;&gt;http://rubygems.org/&lt;/a&gt; (dawny gemcutter.org)&lt;/p&gt;

&lt;p&gt;Jedną z ciekawych funkcji RVM jest możliwość definiowania różnych nazwanych zbiorów gemów które można przełączać w ramach jednego interpretera. (domyślnym zbiorem gemów jest %global)&lt;/p&gt;

&lt;p&gt;Tworzymy zbiór gemów odpowiedzialny za testowanie Rails w wersji &lt;strong&gt;3.0 pre&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rvm gemset create rails3pre
Gemset &lt;span class=&quot;s1&quot;&gt;&amp;#39;rails3pre&amp;#39;&lt;/span&gt; created.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie wybieramy go jako bierzący:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rvm 1.9.1%rails3pre

mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rvm list

rvm &lt;span class=&quot;nv&quot;&gt;Rubies&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt; ruby-1.9.1-p378 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; x86_64 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

Default Ruby &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;new shells&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

   ruby-1.9.1-p378 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; x86_64 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

System Ruby

   system &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; x86_64 i386 ppc &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie instalujemy Ruby on Rails&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;gem install rails --pre

Due to a rubygems bug, you must uninstall older versions of the bundler gem &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;0.9 to work.
If you still need bundler 0.8, install the &lt;span class=&quot;s1&quot;&gt;&amp;#39;bundler08&amp;#39;&lt;/span&gt; gem.
Successfully installed i18n-0.3.5
Successfully installed tzinfo-0.3.16
Successfully installed builder-2.1.2
Successfully installed memcache-client-1.7.8
Successfully installed activesupport-3.0.0.beta
Successfully installed activemodel-3.0.0.beta
Successfully installed rack-1.1.0
Successfully installed rack-test-0.5.3
Successfully installed rack-mount-0.4.7
Successfully installed abstract-1.0.0
Successfully installed erubis-2.6.5
Successfully installed actionpack-3.0.0.beta
Successfully installed arel-0.2.1
Successfully installed activerecord-3.0.0.beta
Successfully installed activeresource-3.0.0.beta
Successfully installed mime-types-1.16
Successfully installed mail-2.1.3
Successfully installed text-hyphen-1.0.0
Successfully installed text-format-1.0.0
Successfully installed actionmailer-3.0.0.beta
Successfully installed thor-0.13.4
Successfully installed railties-3.0.0.beta
Successfully installed bundler-0.9.9
Successfully installed rails-3.0.0.beta
24 gems installed
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;i18n-0.3.5...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;tzinfo-0.3.16...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;builder-2.1.2...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;memcache-client-1.7.8...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;activesupport-3.0.0.beta...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;activemodel-3.0.0.beta...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;rack-1.1.0...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;rack-test-0.5.3...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;rack-mount-0.4.7...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;abstract-1.0.0...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;erubis-2.6.5...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;actionpack-3.0.0.beta...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;arel-0.2.1...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;activerecord-3.0.0.beta...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;activeresource-3.0.0.beta...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;mime-types-1.16...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;mail-2.1.3...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;text-hyphen-1.0.0...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;text-format-1.0.0...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;actionmailer-3.0.0.beta...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;thor-0.13.4...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;railties-3.0.0.beta...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;bundler-0.9.9...
Installing ri documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;rails-3.0.0.beta...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;i18n-0.3.5...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;tzinfo-0.3.16...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;builder-2.1.2...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;memcache-client-1.7.8...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;activesupport-3.0.0.beta...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;activemodel-3.0.0.beta...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;rack-1.1.0...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;rack-test-0.5.3...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;rack-mount-0.4.7...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;abstract-1.0.0...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;erubis-2.6.5...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;actionpack-3.0.0.beta...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;arel-0.2.1...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;activerecord-3.0.0.beta...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;activeresource-3.0.0.beta...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;mime-types-1.16...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;mail-2.1.3...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;text-hyphen-1.0.0...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;text-format-1.0.0...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;actionmailer-3.0.0.beta...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;thor-0.13.4...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;railties-3.0.0.beta...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;bundler-0.9.9...
Installing RDoc documentation &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;rails-3.0.0.beta...
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Aby upewnić się że pracujemy na naszym zbiorze gemów przełączamy się na domyślny i weryfikujemy że nie ma zainstalowanych gemów związanych z rails 3&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rvm 1.9.1
mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;gem list

*** LOCAL GEMS ***

rake &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.8.7&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
rubygems-update &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.3.6&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie wracamy ponownie do naszego zbioru &lt;strong&gt;rails3pre&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rvm 1.9.1%rails3pre
mac:~ andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;gem list

*** LOCAL GEMS ***

abstract &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.0.0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
actionmailer &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
actionpack &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
activemodel &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
activerecord &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
activeresource &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
activesupport &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
arel &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.2.1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
builder &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2.1.2&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
bundler &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.9.9&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
erubis &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2.6.5&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
i18n &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.3.5&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
mail &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2.1.3&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
memcache-client &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.7.8&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
mime-types &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.16&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
rack &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.1.0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
rack-mount &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.4.7&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
rack-test &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.5.3&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
rails &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
railties &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
rake &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.8.7&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
rubygems-update &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.3.6&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
text-format &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.0.0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
text-hyphen &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.0.0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
thor &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.13.4&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
tzinfo &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.3.16&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Kolejnym krokiem jest stworzenie naszej przykładowej aplikacji&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:work andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rails testapp -d postgresql
      create  
      create  README
      create  .gitignore
      create  Rakefile
      create  config.ru
      create  Gemfile
      create  app
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/models
      create  app/views/layouts
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookie_verification_secret.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/session_store.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  log
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  public/images
      create  public/images/rails.png
      create  public/stylesheets
      create  public/stylesheets/.gitkeep
      create  public/javascripts
      create  public/javascripts/application.js
      create  public/javascripts/controls.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/effects.js
      create  public/javascripts/prototype.js
      create  public/javascripts/rails.js
      create  script
      create  script/rails
      create  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;      &lt;/span&gt;create  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/performance/browsing_test.rb
      create  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/test_helper.rb
      create  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/fixtures
      create  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/functional
      create  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/integration
      create  &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/unit
      create  tmp
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
  
mac:work andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;testapp/
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Instalujemy zależności za pomocą narzędzia &lt;strong&gt;bundler&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;bundle -h
Tasks:
  bundle check        &lt;span class=&quot;c&quot;&gt;# Checks if the dependencies listed in Gemfile are satisfied by currently installed gems&lt;/span&gt;
  bundle &lt;span class=&quot;nb&quot;&gt;exec&lt;/span&gt;         &lt;span class=&quot;c&quot;&gt;# Run the command in context of the bundle&lt;/span&gt;
  bundle &lt;span class=&quot;nb&quot;&gt;help&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;TASK&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Describe available tasks or one specific task&lt;/span&gt;
  bundle init         &lt;span class=&quot;c&quot;&gt;# Generates a Gemfile into the current working directory&lt;/span&gt;
  bundle install      &lt;span class=&quot;c&quot;&gt;# Install the current environment to the system&lt;/span&gt;
  bundle lock         &lt;span class=&quot;c&quot;&gt;# Locks the bundle to the current set of dependencies, including all child dependencies.&lt;/span&gt;
  bundle package      &lt;span class=&quot;c&quot;&gt;# Locks and then caches all of the gems into vendor/cache&lt;/span&gt;
  bundle show         &lt;span class=&quot;c&quot;&gt;# Shows all gems that are part of the bundle.&lt;/span&gt;
  bundle unlock       &lt;span class=&quot;c&quot;&gt;# Unlock the bundle. This allows gem versions to be changed&lt;/span&gt;
  bundle version      &lt;span class=&quot;c&quot;&gt;# Prints the bundler&amp;#39;s version information&lt;/span&gt;

mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;bundle install
Fetching &lt;span class=&quot;nb&quot;&gt;source &lt;/span&gt;index from http://gemcutter.org/
Resolving dependencies
Installing abstract &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.0.0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing actionmailer &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing actionpack &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing activemodel &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing activerecord &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing activeresource &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing activesupport &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing arel &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.2.1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing builder &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2.1.2&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing bundler &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.9.9&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing erubis &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2.6.5&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing i18n &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.3.5&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing mail &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2.1.3&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing memcache-client &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.7.8&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing mime-types &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.16&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing pg &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.8.0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from rubygems repository at http://gemcutter.org/ with native extensions 
Installing rack &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.1.0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing rack-mount &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.4.7&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing rack-test &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.5.3&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing rails &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing railties &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3.0.0.beta&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing rake &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.8.7&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing text-format &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.0.0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing text-hyphen &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1.0.0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing thor &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.13.4&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Installing tzinfo &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.3.16&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; from system gems 
Your bundle is &lt;span class=&quot;nb&quot;&gt;complete&lt;/span&gt;!
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;W tym momencie możemy zmodyfikować plik &lt;strong&gt;.gitignore&lt;/strong&gt; taka aby wyglądał następująco:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;.bundle                                                                                                                           
.DS_Store                                                                                                                         
db/*.sqlite3                                                                                                                      
log/*.log                                                                                                                         
tmp/**/*                                                                                                                          
config/database.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie modyfikujemy plik &lt;strong&gt;config/database.yml&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;yaml&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# PostgreSQL. Versions 7.4 and 8.x are supported.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Install the ruby-postgres driver:&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   gem install ruby-postgres&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# On Mac OS X:&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   gem install ruby-postgres -- --include=/usr/local/pgsql&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# On Windows:&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   gem install ruby-postgres&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#       Choose the win32 build.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#       Install PostgreSQL and put its /bin directory on your path.&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;&amp;amp;base&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;postgresql&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;unicode&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;pool&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;5&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;postgres&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;

&lt;span class=&quot;l-Scalar-Plain&quot;&gt;development&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;testapp_development&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;*base&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Connect on a TCP socket. Omitted by default since the client uses a&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# domain socket that doesn&amp;#39;t need configuration. Windows does not have&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# domain sockets, so uncomment these lines.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#host: localhost&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#port: 5432&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Schema search path. The server defaults to $user,public&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#schema_search_path: myapp,sharedapp,public&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Minimum log levels, in increasing order:&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#   debug5, debug4, debug3, debug2, debug1,&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#   log, notice, warning, error, fatal, and panic&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# The server defaults to notice.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#min_messages: warning&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Warning: The database defined as &amp;quot;test&amp;quot; will be erased and&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# re-generated from your development database when you run &amp;quot;rake&amp;quot;.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Do not set this db to the same as development or production.&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;testapp_test&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;*base&lt;/span&gt;

&lt;span class=&quot;l-Scalar-Plain&quot;&gt;production&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;testapp_production&lt;/span&gt;
  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;*base&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Kopiujemy plik jako przykładowy:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;cp config/database.yml config/database.yml.example
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Możemy w tym momencie również się rozejrzeć po aplikacji i zadaniach &lt;strong&gt;rake&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rake -T
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;in /Users/andrzejsliwa/work/testapp&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
rake about                                &lt;span class=&quot;c&quot;&gt;# Explain the current environment&lt;/span&gt;
rake db:abort_if_pending_migrations       &lt;span class=&quot;c&quot;&gt;# Raises an error if there are pending migrations&lt;/span&gt;
rake db:charset                           &lt;span class=&quot;c&quot;&gt;# Retrieves the charset for the current environment&amp;#39;s database&lt;/span&gt;
rake db:collation                         &lt;span class=&quot;c&quot;&gt;# Retrieves the collation for the current environment&amp;#39;s database&lt;/span&gt;
rake db:create                            &lt;span class=&quot;c&quot;&gt;# Create the database defined in config/database.yml for the current Rails.env - al...&lt;/span&gt;
rake db:create:all                        &lt;span class=&quot;c&quot;&gt;# Create all the local databases defined in config/database.yml&lt;/span&gt;
rake db:drop                              &lt;span class=&quot;c&quot;&gt;# Drops the database for the current Rails.env&lt;/span&gt;
rake db:drop:all                          &lt;span class=&quot;c&quot;&gt;# Drops all the local databases defined in config/database.yml&lt;/span&gt;
rake db:fixtures:identify                 &lt;span class=&quot;c&quot;&gt;# Search for a fixture given a LABEL or ID.&lt;/span&gt;
rake db:fixtures:load                     &lt;span class=&quot;c&quot;&gt;# Load fixtures into the current environment&amp;#39;s database.&lt;/span&gt;
rake db:forward                           &lt;span class=&quot;c&quot;&gt;# Pushes the schema to the next version.&lt;/span&gt;
rake db:migrate                           &lt;span class=&quot;c&quot;&gt;# Migrate the database through scripts in db/migrate and update db/schema.rb by inv...&lt;/span&gt;
rake db:migrate:down                      &lt;span class=&quot;c&quot;&gt;# Runs the &amp;quot;down&amp;quot; for a given migration VERSION.&lt;/span&gt;
rake db:migrate:redo                      &lt;span class=&quot;c&quot;&gt;# Rollbacks the database one migration and re migrate up.&lt;/span&gt;
rake db:migrate:reset                     &lt;span class=&quot;c&quot;&gt;# Resets your database using your migrations for the current environment&lt;/span&gt;
rake db:migrate:up                        &lt;span class=&quot;c&quot;&gt;# Runs the &amp;quot;up&amp;quot; for a given migration VERSION.&lt;/span&gt;
rake db:reset                             &lt;span class=&quot;c&quot;&gt;# Drops and recreates the database from db/schema.rb for the current environment an...&lt;/span&gt;
rake db:rollback                          &lt;span class=&quot;c&quot;&gt;# Rolls the schema back to the previous version.&lt;/span&gt;
rake db:schema:dump                       &lt;span class=&quot;c&quot;&gt;# Create a db/schema.rb file that can be portably used against any DB supported by AR&lt;/span&gt;
rake db:schema:load                       &lt;span class=&quot;c&quot;&gt;# Load a schema.rb file into the database&lt;/span&gt;
rake db:seed                              &lt;span class=&quot;c&quot;&gt;# Load the seed data from db/seeds.rb&lt;/span&gt;
rake db:sessions:clear                    &lt;span class=&quot;c&quot;&gt;# Clear the sessions table&lt;/span&gt;
rake db:sessions:create                   &lt;span class=&quot;c&quot;&gt;# Creates a sessions migration for use with ActiveRecord::SessionStore&lt;/span&gt;
rake db:setup                             &lt;span class=&quot;c&quot;&gt;# Create the database, load the schema, and initialize with the seed data&lt;/span&gt;
rake db:structure:dump                    &lt;span class=&quot;c&quot;&gt;# Dump the database structure to a SQL file&lt;/span&gt;
rake db:test:clone                        &lt;span class=&quot;c&quot;&gt;# Recreate the test database from the current environment&amp;#39;s database schema&lt;/span&gt;
rake db:test:clone_structure              &lt;span class=&quot;c&quot;&gt;# Recreate the test databases from the development structure&lt;/span&gt;
rake db:test:load                         &lt;span class=&quot;c&quot;&gt;# Recreate the test database from the current schema.rb&lt;/span&gt;
rake db:test:prepare                      &lt;span class=&quot;c&quot;&gt;# Check for pending migrations and load the test schema&lt;/span&gt;
rake db:test:purge                        &lt;span class=&quot;c&quot;&gt;# Empty the test database&lt;/span&gt;
rake db:version                           &lt;span class=&quot;c&quot;&gt;# Retrieves the current schema version number&lt;/span&gt;
rake doc:app                              &lt;span class=&quot;c&quot;&gt;# Build the RDOC HTML Files&lt;/span&gt;
rake doc:clobber_app                      &lt;span class=&quot;c&quot;&gt;# Remove rdoc products&lt;/span&gt;
rake doc:clobber_plugins                  &lt;span class=&quot;c&quot;&gt;# Remove plugin documentation&lt;/span&gt;
rake doc:clobber_rails                    &lt;span class=&quot;c&quot;&gt;# Remove rdoc products&lt;/span&gt;
rake doc:guides                           &lt;span class=&quot;c&quot;&gt;# Generate Rails guides&lt;/span&gt;
rake doc:plugins                          &lt;span class=&quot;c&quot;&gt;# Generate documentation for all installed plugins&lt;/span&gt;
rake doc:rails                            &lt;span class=&quot;c&quot;&gt;# Build the RDOC HTML Files&lt;/span&gt;
rake doc:reapp                            &lt;span class=&quot;c&quot;&gt;# Force a rebuild of the RDOC files&lt;/span&gt;
rake doc:rerails                          &lt;span class=&quot;c&quot;&gt;# Force a rebuild of the RDOC files&lt;/span&gt;
rake log:clear                            &lt;span class=&quot;c&quot;&gt;# Truncates all *.log files in log/ to zero bytes&lt;/span&gt;
rake middleware                           &lt;span class=&quot;c&quot;&gt;# Prints out your Rack middleware stack&lt;/span&gt;
rake notes                                &lt;span class=&quot;c&quot;&gt;# Enumerate all annotations&lt;/span&gt;
rake notes:custom                         &lt;span class=&quot;c&quot;&gt;# Enumerate a custom annotation, specify with ANNOTATION=CUSTOM&lt;/span&gt;
rake notes:fixme                          &lt;span class=&quot;c&quot;&gt;# Enumerate all FIXME annotations&lt;/span&gt;
rake notes:optimize                       &lt;span class=&quot;c&quot;&gt;# Enumerate all OPTIMIZE annotations&lt;/span&gt;
rake notes:todo                           &lt;span class=&quot;c&quot;&gt;# Enumerate all TODO annotations&lt;/span&gt;
rake rails:freeze:edge                    &lt;span class=&quot;c&quot;&gt;# The freeze:edge command has been deprecated, specify the path setting in your app...&lt;/span&gt;
rake rails:freeze:gems                    &lt;span class=&quot;c&quot;&gt;# The rails:freeze:gems is deprecated, please use bundle install instead&lt;/span&gt;
rake rails:template                       &lt;span class=&quot;c&quot;&gt;# Applies the template supplied by LOCATION=/path/to/template&lt;/span&gt;
rake rails:unfreeze                       &lt;span class=&quot;c&quot;&gt;# The unfreeze command has been deprecated, please use bundler commands instead&lt;/span&gt;
rake rails:update                         &lt;span class=&quot;c&quot;&gt;# Update both configs, scripts and public/javascripts from Rails&lt;/span&gt;
rake rails:update:application_controller  &lt;span class=&quot;c&quot;&gt;# Rename application.rb to application_controller.rb&lt;/span&gt;
rake rails:update:configs                 &lt;span class=&quot;c&quot;&gt;# Update config/boot.rb from your current rails install&lt;/span&gt;
rake rails:update:javascripts             &lt;span class=&quot;c&quot;&gt;# Update Prototype javascripts from your current rails install&lt;/span&gt;
rake rails:update:scripts                 &lt;span class=&quot;c&quot;&gt;# Adds new scripts to the application script/ directory&lt;/span&gt;
rake routes                               &lt;span class=&quot;c&quot;&gt;# Print out all defined routes in match order, with names.&lt;/span&gt;
rake secret                               &lt;span class=&quot;c&quot;&gt;# Generate a crytographically secure secret key.&lt;/span&gt;
rake stats                                &lt;span class=&quot;c&quot;&gt;# Report code statistics (KLOCs, etc) from the application&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;                                 &lt;span class=&quot;c&quot;&gt;# Run all unit, functional and integration tests&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;:benchmark                       &lt;span class=&quot;c&quot;&gt;# Run tests for {:benchmark=&amp;gt;&amp;quot;db:test:prepare&amp;quot;} / Benchmark the performance tests&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;:functionals                     &lt;span class=&quot;c&quot;&gt;# Run tests for {:functionals=&amp;gt;&amp;quot;db:test:prepare&amp;quot;} / Run the functional tests in tes...&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;:integration                     &lt;span class=&quot;c&quot;&gt;# Run tests for {:integration=&amp;gt;&amp;quot;db:test:prepare&amp;quot;} / Run the integration tests in te...&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;:plugins                         &lt;span class=&quot;c&quot;&gt;# Run tests for {:plugins=&amp;gt;:environment} / Run the plugin tests in vendor/plugins/*...&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;:profile                         &lt;span class=&quot;c&quot;&gt;# Run tests for {:profile=&amp;gt;&amp;quot;db:test:prepare&amp;quot;} / Profile the performance tests&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;:recent                          &lt;span class=&quot;c&quot;&gt;# Run tests for {:recent=&amp;gt;&amp;quot;db:test:prepare&amp;quot;} / Test recent changes&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;:uncommitted                     &lt;span class=&quot;c&quot;&gt;# Run tests for {:uncommitted=&amp;gt;&amp;quot;db:test:prepare&amp;quot;} / Test changes since last checkin...&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;:units                           &lt;span class=&quot;c&quot;&gt;# Run tests for {:units=&amp;gt;&amp;quot;db:test:prepare&amp;quot;} / Run the unit tests in test/unit&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt;:zones:all                       &lt;span class=&quot;c&quot;&gt;# Displays names of all time zones recognized by the Rails TimeZone class, grouped ...&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt;:zones:local                     &lt;span class=&quot;c&quot;&gt;# Displays names of time zones recognized by the Rails TimeZone class with the same...&lt;/span&gt;
rake &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt;:zones:us                        &lt;span class=&quot;c&quot;&gt;# Displays names of US time zones recognized by the Rails TimeZone class, grouped b...&lt;/span&gt;
rake tmp:cache:clear                      &lt;span class=&quot;c&quot;&gt;# Clears all files and directories in tmp/cache&lt;/span&gt;
rake tmp:clear                            &lt;span class=&quot;c&quot;&gt;# Clear session, cache, and socket files from tmp/&lt;/span&gt;
rake tmp:create                           &lt;span class=&quot;c&quot;&gt;# Creates tmp directories for sessions, cache, sockets, and pids&lt;/span&gt;
rake tmp:pids:clear                       &lt;span class=&quot;c&quot;&gt;# Clears all files in tmp/pids&lt;/span&gt;
rake tmp:sessions:clear                   &lt;span class=&quot;c&quot;&gt;# Clears all files in tmp/sessions&lt;/span&gt;
rake tmp:sockets:clear                    &lt;span class=&quot;c&quot;&gt;# Clears all files in tmp/sockets&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;W wersji 3.0 ulegl zmianie sposób wywoływania podstawowych poleceń, zastąpiono pojedyńcze skrypty poleceniem rails i odpowiednim parametrem (lub jego skrutem):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rails -h
Usage: rails COMMAND &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;ARGS&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

The most common rails commands are:
 generate    Generate new code &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;short-cut &lt;span class=&quot;nb&quot;&gt;alias&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;g&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 console     Start the Rails console &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;short-cut &lt;span class=&quot;nb&quot;&gt;alias&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 server      Start the Rails server &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;short-cut &lt;span class=&quot;nb&quot;&gt;alias&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;s&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 dbconsole   Start a console &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;the database specified in config/database.yml
             &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;short-cut &lt;span class=&quot;nb&quot;&gt;alias&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&amp;quot;db&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

In addition to those, there are:
 application  Generate the Rails application code
 destroy      Undo code generated with &lt;span class=&quot;s2&quot;&gt;&amp;quot;generate&amp;quot;&lt;/span&gt;
 benchmarker  See how fast a piece of code runs
 profiler     Get profile information from a piece of code
 plugin       Install a plugin
 runner       Run a piece of code in the application environment

All commands can be run with -h &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;more information.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Kolejnym krokiem przed uruchomieniem naszej przykladowej aplikacji jest stworzenie niezbędnych baz oraz uruchomienie serwera:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rake db:create:all
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;in /Users/andrzejsliwa/work/testapp&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rails &lt;span class=&quot;nv&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt; Booting &lt;span class=&quot;nv&quot;&gt;WEBrick&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt; Rails 3.0.0.beta application starting in development on http://0.0.0.0:3000
&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt; Call with -d to &lt;span class=&quot;nv&quot;&gt;detach&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt; Ctrl-C to shutdown server
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;2010-02-26 19:37:50&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; INFO  WEBrick 1.3.1
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;2010-02-26 19:37:50&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; INFO  ruby 1.9.1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2010-01-10&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;i386-darwin10.2.0&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;2010-02-26 19:37:50&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; INFO  WEBrick::HTTPServer#start: &lt;span class=&quot;nv&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;44009 &lt;span class=&quot;nv&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;3000
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Teraz możemy użyć generatorów które zostały w wersji 3.0 w całości przebudowane (tym samym stając się nie kompatybilne z poprzednią wersją). Między innymi wprowadzono w nich uchwyty pozwalające na wymienne stosowanie np. frameworków testowania, widoku itp:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;r g 
Usage: rails generate GENERATOR &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;args&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;options&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

General options:
  -h, &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;--help&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;     &lt;span class=&quot;c&quot;&gt;# Print generators options and usage&lt;/span&gt;
  -p, &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;--pretend&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Run but do not make any changes&lt;/span&gt;
  -f, &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;--force&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;    &lt;span class=&quot;c&quot;&gt;# Overwrite files that already exist&lt;/span&gt;
  -s, &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;--skip&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;     &lt;span class=&quot;c&quot;&gt;# Skip files that already exist&lt;/span&gt;
  -q, &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;--quiet&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;    &lt;span class=&quot;c&quot;&gt;# Supress status output&lt;/span&gt;

Please choose a generator below.

Rails:
  controller
  generator
  helper
  integration_test
  mailer
  metal
  migration
  model
  model_subclass
  observer
  performance_test
  plugin
  resource
  scaffold
  scaffold_controller
  session_migration
  stylesheets

ActiveRecord:
  active_record:migration
  active_record:model
  active_record:observer
  active_record:session_migration

Erb:
  erb:controller
  erb:mailer
  erb:scaffold

TestUnit:
  test_unit:controller
  test_unit:helper
  test_unit:integration
  test_unit:mailer
  test_unit:model
  test_unit:observer
  test_unit:performance
  test_unit:plugin
  test_unit:scaffold


mac-2:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;r g scaffold Post title:string content:text
      invoke  active_record
      create    db/migrate/20100226184313_create_posts.rb
      create    app/models/post.rb
      invoke    test_unit
      create      &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/unit/post_test.rb
      create      &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/fixtures/posts.yml
       route  resources :posts
      invoke  scaffold_controller
      create    app/controllers/posts_controller.rb
      invoke    erb
      create      app/views/posts
      create      app/views/posts/index.html.erb
      create      app/views/posts/edit.html.erb
      create      app/views/posts/show.html.erb
      create      app/views/posts/new.html.erb
      create      app/views/posts/_form.html.erb
      create      app/views/layouts/posts.html.erb
      invoke    test_unit
      create      &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/functional/posts_controller_test.rb
      invoke    helper
      create      app/helpers/posts_helper.rb
      invoke      test_unit
      create        &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/unit/helpers/posts_helper_test.rb
      invoke  stylesheets
      create    public/stylesheets/scaffold.css
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Na tym etapie usuwamy zbędne pliki:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rm public/index.html 
mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rm public/favicon.ico
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Migrujemy bazę danych:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rake db:migrate
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;in /Users/andrzejsliwa/work/testapp&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;  CreatePosts: &lt;span class=&quot;nv&quot;&gt;migrating&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;====================================================&lt;/span&gt;
-- create_table&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;:posts&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
NOTICE:  CREATE TABLE will create implicit sequence &lt;span class=&quot;s2&quot;&gt;&amp;quot;posts_id_seq&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;serial column &lt;span class=&quot;s2&quot;&gt;&amp;quot;posts.id&amp;quot;&lt;/span&gt;
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index &lt;span class=&quot;s2&quot;&gt;&amp;quot;posts_pkey&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;table &lt;span class=&quot;s2&quot;&gt;&amp;quot;posts&amp;quot;&lt;/span&gt;
   -&amp;gt; 0.0073s
&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;  CreatePosts: migrated &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.0074s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===========================================&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Oraz definiujemy routing:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;Testapp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;routes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;draw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:posts&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
  
  &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:to&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;posts#index&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Tak przygotowaną aplikacje, po przetestowaniu możemy dodać do repozytorium gita:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git init
Initialized empty Git repository in /Users/andrzejsliwa/work/testapp/.git/
mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add .
mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git status
&lt;span class=&quot;c&quot;&gt;# On branch master&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Initial commit&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Changes to be committed:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   (use &amp;quot;git rm --cached &amp;lt;file&amp;gt;...&amp;quot; to unstage)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   .gitignore&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   Gemfile&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   README&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   Rakefile&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   app/controllers/application_controller.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   app/controllers/posts_controller.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   app/helpers/application_helper.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   app/helpers/posts_helper.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   app/models/post.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   app/views/layouts/posts.html.erb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   app/views/posts/_form.html.erb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   app/views/posts/edit.html.erb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   app/views/posts/index.html.erb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   app/views/posts/new.html.erb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   app/views/posts/show.html.erb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config.ru&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/application.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/boot.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/database.yml.example&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/environment.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/environments/development.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/environments/production.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/environments/test.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/initializers/backtrace_silencers.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/initializers/cookie_verification_secret.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/initializers/inflections.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/initializers/mime_types.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/initializers/session_store.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/locales/en.yml&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   config/routes.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   db/migrate/20100226184313_create_posts.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   db/schema.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   db/seeds.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   doc/README_FOR_APP&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   lib/tasks/.gitkeep&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/404.html&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/422.html&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/500.html&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/images/rails.png&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/javascripts/application.js&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/javascripts/controls.js&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/javascripts/dragdrop.js&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/javascripts/effects.js&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/javascripts/prototype.js&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/javascripts/rails.js&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/robots.txt&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/stylesheets/.gitkeep&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   public/stylesheets/scaffold.css&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   script/rails&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   test/fixtures/posts.yml&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   test/functional/posts_controller_test.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   test/performance/browsing_test.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   test/test_helper.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   test/unit/helpers/posts_helper_test.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   test/unit/post_test.rb&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   new file:   vendor/plugins/.gitkeep&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;

mac:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit -m &lt;span class=&quot;s2&quot;&gt;&amp;quot;initial import&amp;quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;root-commit&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; 54399d1&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; initial import
 53 files changed, 8540 insertions&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;+&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 0 deletions&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;-&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
 create mode 100644 .gitignore
 create mode 100644 Gemfile
 create mode 100644 README
 create mode 100644 Rakefile
 create mode 100644 app/controllers/application_controller.rb
 create mode 100644 app/controllers/posts_controller.rb
 create mode 100644 app/helpers/application_helper.rb
 create mode 100644 app/helpers/posts_helper.rb
 create mode 100644 app/models/post.rb
 create mode 100644 app/views/layouts/posts.html.erb
 create mode 100644 app/views/posts/_form.html.erb
 create mode 100644 app/views/posts/edit.html.erb
 create mode 100644 app/views/posts/index.html.erb
 create mode 100644 app/views/posts/new.html.erb
 create mode 100644 app/views/posts/show.html.erb
 create mode 100644 config.ru
 create mode 100644 config/application.rb
 create mode 100644 config/boot.rb
 create mode 100644 config/database.yml.example
 create mode 100644 config/environment.rb
 create mode 100644 config/environments/development.rb
 create mode 100644 config/environments/production.rb
 create mode 100644 config/environments/test.rb
 create mode 100644 config/initializers/backtrace_silencers.rb
 create mode 100644 config/initializers/cookie_verification_secret.rb
 create mode 100644 config/initializers/inflections.rb
 create mode 100644 config/initializers/mime_types.rb
 create mode 100644 config/initializers/session_store.rb
 create mode 100644 config/locales/en.yml
 create mode 100644 config/routes.rb
 create mode 100644 db/migrate/20100226184313_create_posts.rb
 create mode 100644 db/schema.rb
 create mode 100644 db/seeds.rb
 create mode 100644 doc/README_FOR_APP
 create mode 100644 lib/tasks/.gitkeep
 create mode 100644 public/404.html
 create mode 100644 public/422.html
 create mode 100644 public/500.html
 create mode 100644 public/images/rails.png
 create mode 100644 public/javascripts/application.js
 create mode 100644 public/javascripts/controls.js
 create mode 100644 public/javascripts/dragdrop.js
 create mode 100644 public/javascripts/effects.js
 create mode 100644 public/javascripts/prototype.js
 create mode 100644 public/javascripts/rails.js
 create mode 100644 public/robots.txt
 create mode 100644 public/stylesheets/.gitkeep
 create mode 100644 public/stylesheets/scaffold.css
 create mode 100755 script/rails
 create mode 100644 &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/fixtures/posts.yml
 create mode 100644 &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/functional/posts_controller_test.rb
 create mode 100644 &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/performance/browsing_test.rb
 create mode 100644 &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/test_helper.rb
 create mode 100644 &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/unit/helpers/posts_helper_test.rb
 create mode 100644 &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/unit/post_test.rb
 create mode 100644 vendor/plugins/.gitkeep
 
mac-2:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git remote add origin git@github.com:andrzejsliwa/testapp.git
mac-2:testapp andrzejsliwa&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git push origin master
Counting objects: 84, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
Delta compression using up to 2 threads.
Compressing objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;68/68&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
Writing objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;84/84&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 81.08 KiB, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
Total 84 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 2&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, reused 0 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
To git@github.com:andrzejsliwa/testapp.git
* &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;new branch&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;      master -&amp;gt; master
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



</content>
   <updated>2010-02-26T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="rubyonrails" label="rubyonrails" />
   <updated>2010-02-26T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="rvm" label="rvm" />
   <updated>2010-02-26T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="bundler" label="bundler" />
   <updated>2010-02-26T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="ruby191" label="ruby191" />
 </entry>
 
 <entry>
   <id>http://andrzejsliwa.com/2010/02/03/drukowanie-pdf</id>
   <link href="http://andrzejsliwa.github.com/2010/02/03/drukowanie-pdf"/>
   <title>Drukowanie bezpośrednio do PDF</title>
   <author>
     <name>Andrzej Sliwa</name>
     <email>andrzej.sliwa@i-tool.eu</email>
   </author>
   <content type="html">&lt;p&gt;W aplikacjach webowych format &lt;a href=&quot;http://pl.wikipedia.org/wiki/Pdf&quot;&gt;PDF&lt;/a&gt; ugruntował już swoją pozycję. W większości przypadków jest formatem w którym &quot;drukowane&quot; są zarówno faktury, jak i wszelkiej maści dokumenty informacyjne. W przypadku frameworka
Ruby on Rails do tej pory korzystałem z biblioteki &lt;a href=&quot;http://prawn.majesticseacreature.com/&quot;&gt;Prawn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Niestety możliwości tej biblioteki są dość ubogie jeśli chodzi o tworzenie dokumentów mocno customizowanych, wymuszając wręcz rysowanie co bardziej skomplikowanych elementów wizualnych. W powiązaniu z wymaganiami klienta
powodowało to ciągłą, syzyfową pracę, by zapewnić poprawne wyświetlanie dokumentów gdzie treść oraz jej rozkład
mógł się zmieniać.&lt;/p&gt;

&lt;p&gt;Zrażony tymi problemami postanowiłem znaleźć rozwiązanie bazujące na htmlu jako formacie źródłowym dla PDF.
Skierowałem swoje pierwsze kroki w kierunku &lt;a href=&quot;http://github.com&quot;&gt;GitHuba&lt;/a&gt; i tam też znalazłem gotowe rozwiązanie moich problemów
w postaci plugina.&lt;/p&gt;

&lt;p&gt;Plugin nazywa się &lt;a href=&quot;http://github.com/mileszs/wicked_pdf&quot;&gt;Wicket PDF&lt;/a&gt; i jest tak naprawdę prostym wrapperem dla programu uruchamianego z linii poleceń
&lt;a href=&quot;http://code.google.com/p/wkhtmltopdf/&quot;&gt;wkhtmltopdf&lt;/a&gt; (bazujący na webkit).&lt;/p&gt;

&lt;p&gt;Instalacja rozwiązania polega na zainstalowaniu wkhtmltopdf (ze źródeł, bądź z prekompilowanych binarek)&lt;/p&gt;

&lt;p&gt;w przypadku mojego systemu operacyjnego(Mac OSX) wygląda to następująco:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;wget http://wkhtmltopdf.googlecode.com/files/wkhtmltopdf-0.9.1-OS-X.i368
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo mv wkhtmltopdf-0.9.1-OS-X.i368 /opt/local/bin/wkhtmltopdf
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo chmod +x wkhtmltopdf
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;możemy oczywiście przetestować funkcjonowanie tego programu:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;wkhtmltopdf www.google.pl google.pdf
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;lub&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;wkhtmltopdf file:///Users/andrzejsliwa/Desktop/test.html test.pdf
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;następnie instalujemy sam plugin:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;script/plugin install git://github.com/mileszs/wicked_pdf.git
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;script/generate wicked_pdf
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;tak zainstalowany plugin można bez problemu wykorzystać w następujący sposób:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# GET /pages/1&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# GET /pages/1.xml&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;show&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;respond_to&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# show.html.erb&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xml&lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;render&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:xml&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@page&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pdf&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;render&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:Pdf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;pages/show.html.erb&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:wkhtmltopdf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/opt/local/bin/wkhtmlopdf&amp;#39;&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;generowanie linków dla dokumentów pdf może wyglądać następująco:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;%= link_to &amp;quot;PDF&amp;quot;, page_path(@page, :format =&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;pdf&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:target&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;_blank&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Lektura obowiązkowa:
&lt;a href=&quot;http://github.com/mileszs/wicked_pdf&quot;&gt;http://github.com/mileszs/wicked_pdf&lt;/a&gt;
&lt;a href=&quot;http://code.google.com/p/wkhtmltopdf/&quot;&gt;http://code.google.com/p/wkhtmltopdf/&lt;/a&gt;&lt;/p&gt;
</content>
   <updated>2010-02-03T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="rubyonrails" label="rubyonrails" />
 </entry>
 
 <entry>
   <id>http://andrzejsliwa.com/2010/01/04/oszukiwanie-jest-fajne</id>
   <link href="http://andrzejsliwa.github.com/2010/01/04/oszukiwanie-jest-fajne"/>
   <title>Oszukiwanie jest fajne</title>
   <author>
     <name>Andrzej Sliwa</name>
     <email>andrzej.sliwa@i-tool.eu</email>
   </author>
   <content type="html">&lt;p&gt;W codziennej pracy często zdarza się sytuacja kiedy potrzebujemy informacji odnośnie jakiegoś narzędzia, biblioteki itp. Wtedy ruszamy często do &lt;a href=&quot;http://google.pl&quot;&gt;Googla&lt;/a&gt;. Lecz można również... oszukiwać (&lt;strong&gt;cheat&lt;/strong&gt; - oszustwo) instalując taki oto przydatny wynalazek ułatwiający nam życie:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;gem install cheat
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;i od razu możemy z niego korzystać, powiedzmy że potrzebuję informacji jak używać git'a:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;cheat git
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;I dostaniemy taki oto &lt;strong&gt;cheatsheet&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;git:
  Setup
  -----

  git clone &amp;lt;repo&amp;gt;
    clone the repository specified by &amp;lt;repo&amp;gt;; this is similar to &lt;span class=&quot;s2&quot;&gt;&amp;quot;checkout&amp;quot;&lt;/span&gt; in
    some other version control systems such as Subversion and CVS

  Add colors to your ~/.gitconfig file:

    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;color&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;ui&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; auto
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;color &lt;span class=&quot;s2&quot;&gt;&amp;quot;branch&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;current&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; yellow reverse
      &lt;span class=&quot;nb&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; yellow
      &lt;span class=&quot;nv&quot;&gt;remote&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; green
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;color &lt;span class=&quot;s2&quot;&gt;&amp;quot;diff&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; yellow bold
      &lt;span class=&quot;nv&quot;&gt;frag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; magenta bold
      &lt;span class=&quot;nv&quot;&gt;old&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; red bold
      &lt;span class=&quot;nv&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; green bold
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;color &lt;span class=&quot;s2&quot;&gt;&amp;quot;status&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;added&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; yellow
      &lt;span class=&quot;nv&quot;&gt;changed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; green
      &lt;span class=&quot;nv&quot;&gt;untracked&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; cyan

  Highlight whitespace in diffs

    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;color&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;ui&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;color &lt;span class=&quot;s2&quot;&gt;&amp;quot;diff&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;whitespace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; red reverse
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;core&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;whitespace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;fix,-indent-with-non-tab,trailing-space,cr-at-eol

  Add aliases to your ~/.gitconfig file:

    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;st&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; status
      &lt;span class=&quot;nv&quot;&gt;ci&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; commit
      &lt;span class=&quot;nv&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; branch
      &lt;span class=&quot;nv&quot;&gt;co&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; checkout
      &lt;span class=&quot;nv&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; diff
      &lt;span class=&quot;nv&quot;&gt;lg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; log -p


  Configuration
  -------------

  git config -e &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;--global&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    edit the .git/config &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;or ~/.gitconfig&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; file in your &lt;span class=&quot;nv&quot;&gt;$EDITOR&lt;/span&gt;

  git config --global user.name &lt;span class=&quot;s1&quot;&gt;&amp;#39;John Doe&amp;#39;&lt;/span&gt;
  git config --global user.email johndoe@example.com
    sets your name and email &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;commit messages

  ...
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Albo informacji odnośnie np. rspec'a:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cheat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rspec&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;I dostaniemy taki oto &lt;strong&gt;cheatsheet&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;rspec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;INSTALL&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;=======&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;INSTALL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rspec&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;=============&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rspec&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;OR&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;/script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plugin&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dchelimsky&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rspec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;git&lt;/span&gt;

    &lt;span class=&quot;no&quot;&gt;INSTALL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rspec_on_rails&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plugin&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;=============================&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;/script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plugin&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dchelimsky&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rspec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;git&lt;/span&gt;


  &lt;span class=&quot;no&quot;&gt;BOOTSTRAP&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;THE&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;APP&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;=================&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;/script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;generate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rspec&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spec_helper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;previous_failures&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txt&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spec_server&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt;



  &lt;span class=&quot;no&quot;&gt;HOW&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;TO&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;USE&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;==========&lt;/span&gt;

    &lt;span class=&quot;no&quot;&gt;COMMAND&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;LINE&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;=============&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;specdoc&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rspec&lt;/span&gt;

    &lt;span class=&quot;no&quot;&gt;RAILS&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;=============&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;/script&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;generate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rspec_model&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:plugins&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# generates local docs for your app&amp;#39;s plugins&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# lists all rspec rake tasks&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# run all specs&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SPEC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;models&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mymodel_spec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SPEC_OPTS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-e &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;should do&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;  something&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#run a single spec&lt;/span&gt;




  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;UserSpecHelper&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;valid_user_attributes&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:email&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;joe@bloggs.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;:username&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;joebloggs&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;abcdefg&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;


  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;A User (in general)&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;UserSpecHelper&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;should be invalid without a username&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;pending&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;some other thing we depend on&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;valid_user_attributes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_valid&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error_on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;is required&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;username&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;someusername&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_valid&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;no&quot;&gt;SHOULDA&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;COULDA&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;WOULDA&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;=====================&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;satisfy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;satisfy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;not_equal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_close&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tolerance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_close&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tolerance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;predicate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optional&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_predicate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optional&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;predicate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optional&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_predicate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optional&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Samantha&amp;#39;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;regex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;regex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_an_instance_of&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_an_instance_of&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_a_kind_of&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_a_kind_of&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;respond_to&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;respond_to&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;OLD&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:*&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_raise&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# not available anymore&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NEW&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:*&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a_call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raise_error&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a_call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raise_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a_call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raise_error&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a_call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raise_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_not&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;things&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_at_least&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;things&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_at_most&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;things&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors_on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;proc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;approve!&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;change&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;thing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;AWAITING_APPROVAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;APPROVED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;proc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destroy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;change&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Thing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;by&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;no&quot;&gt;Mocks&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Stubs&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;===============&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;user_mock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;User&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;user_mock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_receive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:authenticate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;password&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;and_return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;user_mock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_receive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:coffee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exactly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;times&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;and_return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:americano&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;user_mock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should_receive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:coffee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exactly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;times&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;and_raise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NotEnoughCoffeeExc&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;ption&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;people_stub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;people&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;people_stub&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stub!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;and_yield&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;people_stub&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stub!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:bad_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;and_raise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;RuntimeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;user_stub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;User&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:username&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;pat&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:email&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&amp;quot;pat@example.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Prawda że fajnie jest oszukiwać ! ;)&lt;/p&gt;

&lt;p&gt;Lektura obowiązkowa:
&lt;a href=&quot;http://cheat.errtheblog.com/&quot;&gt;http://cheat.errtheblog.com/&lt;/a&gt;&lt;/p&gt;
</content>
   <updated>2010-01-04T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="rubyonrails" label="rubyonrails" />
 </entry>
 
 <entry>
   <id>http://andrzejsliwa.com/2010/01/03/radrails-3-w-koncu-zrozumieli-ze-potrzebny-jest-textmate</id>
   <link href="http://andrzejsliwa.github.com/2010/01/03/radrails-3-w-koncu-zrozumieli-ze-potrzebny-jest-textmate"/>
   <title>RadRails 3 - w końcu zrozumieli że potrzebny jest "textmate"</title>
   <author>
     <name>Andrzej Sliwa</name>
     <email>andrzej.sliwa@i-tool.eu</email>
   </author>
   <content type="html">

&lt;div style=&quot;background: black;-moz-border-radius: 0.3em;
  -webkit-border-radius: 0.3em;&quot;&gt;
&lt;p style=&quot;margin-left: 8px;&quot;&gt;
&lt;object type=&quot;application/x-shockwave-flash&quot; data=&quot;http://vimeo.com/moogaloop.swf?clip_id=7655277&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=7CA300&amp;amp;fullscreen=1&quot; width=&quot;740&quot; height=&quot;490&quot;&gt;
  &lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /&gt;
  &lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /&gt;
  &lt;param name=&quot;movie&quot; value=&quot;http://vimeo.com/moogaloop.swf?clip_id=7655277&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=7CA300&amp;amp;fullscreen=1&quot; /&gt;
&lt;/object&gt;
&lt;/p&gt;
&lt;/div&gt;




&lt;div style=&quot;background: black;-moz-border-radius: 0.3em;
  -webkit-border-radius: 0.3em;&quot;&gt;
&lt;p style=&quot;margin-left: 8px;&quot;&gt;
&lt;object type=&quot;application/x-shockwave-flash&quot; data=&quot;http://vimeo.com/moogaloop.swf?clip_id=8253946&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=7CA300&amp;amp;fullscreen=1&quot; width=&quot;740&quot; height=&quot;490&quot;&gt;
  &lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /&gt;
  &lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /&gt;
  &lt;param name=&quot;movie&quot; value=&quot;http://vimeo.com/moogaloop.swf?clip_id=8253946&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=7CA300&amp;amp;fullscreen=1&quot; /&gt;
&lt;/object&gt;
&lt;/p&gt;
&lt;/div&gt;


&lt;p&gt;Lektura obowiązkowa:&lt;br/&gt;
&lt;a href=&quot;http://radrails.org/3&quot;&gt;http://radrails.org/3&lt;/a&gt;&lt;/p&gt;
</content>
   <updated>2010-01-03T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="rubyonrails" label="rubyonrails" />
   <updated>2010-01-03T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="git" label="git" />
 </entry>
 
 <entry>
   <id>http://andrzejsliwa.com/2010/01/03/cucumber-zielony-zielony-ogorek</id>
   <link href="http://andrzejsliwa.github.com/2010/01/03/cucumber-zielony-zielony-ogorek"/>
   <title>Cucumber - ogórek, ogórek... zielony ma garniturek</title>
   <author>
     <name>Andrzej Sliwa</name>
     <email>andrzej.sliwa@i-tool.eu</email>
   </author>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://vimeo.com/6563331&quot;&gt;Introduction to Outside-in Development with Cucumber&lt;/a&gt; from &lt;a href=&quot;http://vimeo.com/berry&quot;&gt;Eric Berry&lt;/a&gt; on &lt;a href=&quot;http://vimeo.com&quot;&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;

&lt;div style=&quot;background: black;-moz-border-radius: 0.3em;
  -webkit-border-radius: 0.3em;&quot;&gt;
&lt;p style=&quot;margin-left: 8px;&quot;&gt;
&lt;object type=&quot;application/x-shockwave-flash&quot; data=&quot;http://vimeo.com/moogaloop.swf?clip_id=6563331&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=7CA300&amp;amp;fullscreen=1&quot; width=&quot;740&quot; height=&quot;490&quot;&gt;
  &lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /&gt;
  &lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /&gt;
  &lt;param name=&quot;movie&quot; value=&quot;http://vimeo.com/moogaloop.swf?clip_id=6563331&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=0&amp;amp;show_portrait=0&amp;amp;color=7CA300&amp;amp;fullscreen=1&quot; /&gt;
&lt;/object&gt;
&lt;/p&gt;
&lt;/div&gt;


&lt;p&gt;Lektura obowiązkowa:&lt;br/&gt;
&lt;a href=&quot;http://cukes.info/&quot;&gt;http://cukes.info/&lt;/a&gt;&lt;br/&gt;
&lt;a href=&quot;http://asciicasts.com/episodes/155-beginning-with-cucumber&quot;&gt;http://asciicasts.com/episodes/155-beginning-with-cucumber&lt;/a&gt;&lt;br/&gt;
&lt;a href=&quot;http://asciicasts.com/episodes/159-more-on-cucumber&quot;&gt;http://asciicasts.com/episodes/159-more-on-cucumber&lt;/a&gt;&lt;/p&gt;
</content>
   <updated>2010-01-03T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="rubyonrails" label="rubyonrails" />
   <updated>2010-01-03T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="git" label="git" />
 </entry>
 
 <entry>
   <id>http://andrzejsliwa.com/2010/01/02/szablony-czyli-jak-zautomatyzowac-tworzenie-aplikacji</id>
   <link href="http://andrzejsliwa.github.com/2010/01/02/szablony-czyli-jak-zautomatyzowac-tworzenie-aplikacji"/>
   <title>App Templates - szybki start tworzenia aplikacji</title>
   <author>
     <name>Andrzej Sliwa</name>
     <email>andrzej.sliwa@i-tool.eu</email>
   </author>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://rubyonrails.org&quot;&gt;Ruby on Rails&lt;/a&gt; z wersji na wersję podlega naturalnej ewolucji. Jest to proces ciągły, oparty na reagowaniu jego użytkowników na nowe wymagania stawiane przed frameworkiem. Aktualna gałąź &lt;a href=&quot;http://guides.rubyonrails.org/2_3_release_notes.html&quot;&gt;2.3&lt;/a&gt; wprowadza szereg udogodnień związanych między innymi z automatyzacją procesu tworzenia aplikacji. Wprowadzono prosty język &lt;a href=&quot;http://en.wikipedia.org/wiki/Domain-specific_language&quot;&gt;DSL&lt;/a&gt; za pomocą którego jesteśmy w stanie projektować własne szablony.
Szablony te mogą się na wzajem wywoływać co pozwala na modułowe wykorzystanie.&lt;/p&gt;

&lt;p&gt;Przykład szablonu automatyzującego dodawanie aplikacji do repozytorium &lt;a href=&quot;http://git-scm.com/&quot;&gt;GIT&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;GIT template&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Starting template&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;respond_to?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:already_using&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;TEMPLATE_BASE&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;http://github.com/andrzejsliwa/config/raw/master/templates&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;load_template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/helpers_methods.rb&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@stand_alone&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;already_using&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.git/config&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;GIT&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Remove temp directories.&lt;/span&gt;
&lt;span class=&quot;sx&quot;&gt;%w[cache pids sessions sockets]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;rmdir&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;tmp/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Remove unnecessary files.&lt;/span&gt;
&lt;span class=&quot;sx&quot;&gt;%w[index.html favicon.ico robots.txt]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;public/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;doc/README_FOR_APP&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Hold empty directories touching a .gitignore file&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;find . &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;( -type d -empty &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;) -and &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;( -not -regex ./&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.git.* &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;) -exec touch {}/.gitignore &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Copy database.yml for reuse&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cp&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;config/database.yml&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;config/database.yml.example&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Create root .gitignore file from template&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;config_file&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;.gitignore&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:init&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@stand_alone&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Initial commit&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:commit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-a -m &amp;#39;initial import.&amp;#39;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;GIT template&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Successfully applied template&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Użycie przykładowego szablonu może odbywać się na 2 sposoby:&lt;/p&gt;

&lt;p&gt;w trakcie tworzenia aplikacji:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rails&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;application_name&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;andrzejsliwa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;raw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;master&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;templates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;w dowolnym momencie wykorzystując wbudowany task Rake'a:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rails&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:template&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;LOCATION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;andrzejsliwa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;raw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;master&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;templates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rb&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Zapraszam do zapoznania się z tym mechanizmem, umiejętnie wykorzystany może zaoszczędzić nam mnóstwo czasu związanego z konfiguracją aplikacji.&lt;/p&gt;

&lt;p&gt;Na koniec przykład pliku szablonu nad którym obecnie jeszcze pracuję, a który ma zautomatyzować konfigurację aplikacji pod &lt;a href=&quot;http://cukes.info/&quot;&gt;Cucumber&lt;/a&gt; / &lt;a href=&quot;http://rspec.info/&quot;&gt;Rspec&lt;/a&gt; oraz &lt;a href=&quot;http://github.com/binarylogic/authlogic&quot;&gt;Authologic&lt;/a&gt;. Skrypt ten wykorzystuje wyżej prezentowany &lt;code&gt;git.rb&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;BASE template&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Starting base template&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;TEMPLATE_BASE&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;http://github.com/andrzejsliwa/config/raw/master/templates&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;respond_to?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:already_using&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;load_template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/helpers_methods.rb&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;



&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;authlogic&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;          &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=2.1.3&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;gemcutter&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;          &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=0.2.1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rcov&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;               &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=0.9.7&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;database_cleaner&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=0.4.0&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;webrat&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;             &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=0.6.0&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rspec&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;              &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=1.2.9&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rspec-rails&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=1.2.9&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;cucumber&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;           &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=0.5.3&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;cucumber-rails&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=0.2.2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;autotest&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;           &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=4.1.4&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;autotest-rails&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=4.1.0&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;autotest-fsevent&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=0.1.3&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;autotest-growl&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=0.1.7&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ZenTest&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;            &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=4.2.1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;factory_girl&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;       &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=1.2.3&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;email_spec&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;         &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=0.3.8&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;email_spec&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;gems:install&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;gems:install&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# We don&amp;#39;t like unittest ;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rmdir_r&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Get database.yml file&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;database_yml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:postgresql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Run required generators&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;generate&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:cucumber&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;generate&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:rspec&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;generate&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:email_spec&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;email_spec&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;gt;=0.3.8&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;email_spec&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;cucumber&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Get .autotest config file&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;config_file&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;.autotest&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;rakefile&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rcov.rake&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;lib/tasks/rcov.rake&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rcov.opts&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;spec&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;spec_helper.rb&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;features&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;support/env.rb&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;db:create:all&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;db:migrate&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rake&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;db:test:load&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;load_template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/haml.rb&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yes?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;enable HAML?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;vi&quot;&gt;@is_git&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yes?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;enable GIT?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;load_template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/git.rb&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@is_git&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@is_git&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Initial commit&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:commit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;-a -m &amp;#39;initial import.&amp;#39;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;BASE template&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Successfully applied template&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Wszystkie aktualne źródła znajdują się tutaj:
&lt;a href=&quot;http://github.com/andrzejsliwa/config/tree/master/templates/&quot;&gt;http://github.com/andrzejsliwa/config/tree/master/templates/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lektura obowiązkowa:
&lt;a href=&quot;http://asciicasts.com/episodes/148-app-templates-in-rails-2-3&quot;&gt;http://asciicasts.com/episodes/148-app-templates-in-rails-2-3&lt;/a&gt;
&lt;a href=&quot;http://m.onkey.org/2008/12/4/rails-templates&quot;&gt;http://m.onkey.org/2008/12/4/rails-templates&lt;/a&gt;
&lt;a href=&quot;http://guides.rubyonrails.org/2_3_release_notes.html&quot;&gt;http://guides.rubyonrails.org/2_3_release_notes.html&lt;/a&gt;&lt;/p&gt;
</content>
   <updated>2010-01-02T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="rubyonrails" label="rubyonrails" />
   <updated>2010-01-02T00:00:00-08:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="git" label="git" />
 </entry>
 
 <entry>
   <id>http://andrzejsliwa.com/2009/09/18/django-1-1-instalacja-i-konfiguracja-projektu-na-mac-osx-10-6-snow-leopard-64bit</id>
   <link href="http://andrzejsliwa.github.com/2009/09/18/django-1-1-instalacja-i-konfiguracja-projektu-na-mac-osx-10-6-snow-leopard-64bit"/>
   <title>Instalacja Django 1.1 + konfiguracja projektu na Mac OSX Snow Leopard (64bit)</title>
   <author>
     <name>Andrzej Sliwa</name>
     <email>andrzej.sliwa@i-tool.eu</email>
   </author>
   <content type="html">&lt;p&gt;W ostatnim poście obiecałem wspomnieć jeszcze o &lt;a href=&quot;http://djangoproject.com&quot;&gt;Django&lt;/a&gt;, dzisiaj postaram się przeprowadzić krok po kroku przez konfiguracje środowiska (na przykładzie Mac OSX 10.6 Snow Leopard – 64bit), instalacje stosu programistycznego, uruchomienia projektu oraz konfiguracji wdrożenia. W celu przeprowadzenia instalacji niezbędnych składników niezbędny będzie system portów (&lt;a href=&quot;http://www.macports.org/&quot;&gt;macport&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;W pierwszej kolejności przeprowadzamy uaktualnienie systemu port oraz jego repozytorium wersji, jest to niezbędne gdyż wiele poprawek jest wprowadzanych na bieżąco (tutaj muszę zaznaczyć pochwalić community macporta za szybką reakcje, zgłoszony ticket – problem z py25-graphviz, rozwiązali w 45 minut od zgłoszenia):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo port selfupdate
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie przystępujemy do instalacji &lt;a href=&quot;http://git-scm.com/&quot;&gt;GIT&lt;/a&gt;a z systemu portów (we wcześniejszych postach sugerowałem użycie pre-kompilowanej wersji binarnej, ze względu na błąd w zależnościach gitsvn do sqlite, jednak jak wspomniałem powyżej macport mnie przekonał):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo port install git-core +gitweb +svn
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Kolejnym krokiem jest skonfigurowanie zmiennych GITa (w analogiczny sposób jak w poście dotyczącym Ruby on Rails i Leopard):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config --global user.name &lt;span class=&quot;s2&quot;&gt;&amp;quot;Your Name&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config --global user.email youemail@youdomain.com
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config --global color.branch auto
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config --global color.diff auto
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config --global color.interactive auto
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config --global color.status auto
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git config --global core.editor &lt;span class=&quot;s2&quot;&gt;&amp;quot;mate -w&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;W tym momencie możemy przystąpić do instalacji niezbędnej do naszej pracy bazy danych (w tym przypadku jest to &lt;a href=&quot;http://www.postgresql.org/&quot;&gt;Postgres&lt;/a&gt; w wersji 8.3, którego od dłuższego czasu faworyzuje w stosunku do mysql’a):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo port install postgresql83 postgresql83-server
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo launchctl load -w /Library/LaunchDaemons/org.macports.postgresql83-server.plist
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo mkdir -p /opt/local/var/db/postgresql83/defaultdb
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo chown postgres:postgres /opt/local/var/db/postgresql83/defaultdb
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo su postgres -c &lt;span class=&quot;s1&quot;&gt;&amp;#39;/opt/local/lib/postgresql83/bin/initdb &lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;-D /opt/local/var/db/postgresql83/defaultdb&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnym krokiem jest instalacja &lt;a href=&quot;http://www.python.org/&quot;&gt;Pythona&lt;/a&gt; z systemu portów, co prawda Snow Leopard jest dostarczany z wersją 2.6, lecz mimo wszystko pozwoliłem sobie zainstalować wersję 2.5 (zalecaną do pracy z django):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo port install python25
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo port install python_select
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Musimy jeszcze ustawić w systemie odpowiednie ścieżki i aliasy tak by komendy wskazywały na wersję zainstalowaną przez macporty (uwaga: w momencie instalacji miałem problem związany z błędnym działaniem polecenia select_python, obecnie problem ten już jest rozwiązany):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo python_select python25
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Aby skorzystać z możliwości jakie daje nam Django (obecnie 1.1), należy doinstalować następujące składniki (obsługa bazy postgres, ssl, pil, itd.):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo port install py25-psycopg2 +postgresql83
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo port install py25-crypto py25-chardet py25-dateutil py25-socket-ssl py25-pil py25-pygraphviz
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Poprawność instalacji i konfiguracji Pythona z systemu portu możemy potwierdzić wywołując polecenie:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;python -c &lt;span class=&quot;s2&quot;&gt;&amp;quot;from distutils.sysconfig import get_python_lib; print get_python_lib()&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;wynikiem działania powinna być ścieżka do katalogu &lt;code&gt;…/python2.5/site-packages&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Na tym etapie gotowi jesteśmy zainstalować framework Django wraz z przydatnymi narzędziami:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo easy_install django
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo easy_install south
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo easy_install fabric
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo easy_install django-extensions
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo easy_install django-debug-toolbar
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;W tym momencie możemy utworzyć nasz pierwszy projekt:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;django-admin.py startproject learningdjango
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Efektem wykonania powyższego polecenia jest utworzenie katalogu learningdjango zawierającego pliki naszego projektu:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;tree learningdjango
learningdjango
|-- __init__.py
|-- manage.py
|-- settings.py
&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;-- urls.py
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Teraz jest odpowiedni moment na skonfigurowanie naszego projektu jako repozytorium GIT. W tym celu wykonujemy następujące polecenie z poziomu katalogu naszego projektu&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git init
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Tworzymy również plik &lt;code&gt;.gitignore&lt;/code&gt; w którym definiujemy reguły ignorowania plików przez nasze repozytorium, z następującą zawartością:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;.DS_Store
*.pyc
dev.db
local_settings.py
local_urls.py
media/*
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;następnie dodajemy nasze pliki do systemu wersjonowania i zabezpieczamy:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add .
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit -m &lt;span class=&quot;s2&quot;&gt;&amp;quot;initial import.&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Proponuje również stworzenie brancha (i przełączenie się na niego) w którym będziemy pracowali nad naszą konfiguracją projektu&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git branch first_configuration
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git checkout first_configuration
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Pierwszym niezbędnym krokiem jest stworzenie bazy danych (polecam do tego instalacje pgAdmin z binarek dostępnych na stronie projektu postgres), oraz skonfigurowanie projektu w pliku settings.py.&lt;/p&gt;

&lt;p&gt;W tym celu wprowadzamy następujące zmiany w pliku &lt;code&gt;settings.py&lt;/code&gt;, zmiany te będą miały charakter “produkcyjny”:&lt;/p&gt;

&lt;p&gt;wyłączamy tryb debug (dlaczego to robimy wyjaśnię w kolejnych krokach):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;DEBUG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;TEMPLATE_DEBUG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DEBUG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;następnie konfigurujemy ADMINS (jest to lista osób wraz z ich mailami które zostaną poinformowane w przypadku wystąpienia nie obsłużonych/nie oczekiwanych wyjątków naszej aplikacji – oczywiście gdy wyżej wspomniana opcja DEBUG = False)&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;ADMINS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Andrzej Sliwa&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;moj.mail@moja.domena&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Kolejnym krokiem jest zdefiniowanie konfiguracji bazy danych (postgres):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;DATABASE_ENGINE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;postgresql_psycopg2&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATABASE_NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;learningdjango_prod&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATABASE_USER&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;learningdjango_prod&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATABASE_PASSWORD&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;123;)&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATABASE_HOST&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;127.0.0.1&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATABASE_PORT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie konfigurujemy wysyłanie poczty (za pomocą gmaila)&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;EMAIL_USE_TLS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMAIL_HOST&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;smtp.gmail.com&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMAIL_HOST_USER&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;mojekonto@gmail.com&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMAIL_HOST_PASSWORD&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;123;)&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMAIL_PORT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;587&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Istotnym krokiem w przypadku konfiguracji django jest konfiguracja ścieżek&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;MEDIA_ROOT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/home/andrzejsliwa/webapps/learningdjango/public/media/&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Definiujemy url do plików statycznych takich jak grafika, css itp. (w przypadku wersji produkcyjnej apache zajmuje się hostowaniem plików statycznych)&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;MEDIA_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;http://learningdjango.pl/media/&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Ustawiamy opcje redirectu:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;LOGIN_REDIRECT_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Ustawiamy url do plików panelu administracyjnego&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;ADMIN_MEDIA_PREFIX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;/admin_media/&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie wskazujemy katalog szablonów (na produkcji):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;TEMPLATE_DIRS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;/home/andrzejsliwa/webapps/learningdjango/learningdjango/templates&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Włączamy niezbędne aplikacje:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.auth&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.contenttypes&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.sessions&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.sites&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.admindocs&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.admin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django_extensions&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;south&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Ostatnim niezbędnym składnikiem naszego pliku &lt;code&gt;settings.py&lt;/code&gt; są polecenia:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;local_settings&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Cały plik po naszych zmianach prezentuje się następująco:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;DEBUG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;TEMPLATE_DEBUG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DEBUG&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ADMINS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;Andrzej Sliwa&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;moj.mail@moja.domena&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;MANAGERS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ADMINS&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;DATABASE_ENGINE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;postgresql_psycopg2&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATABASE_NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;learningdjango_prod&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATABASE_USER&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;learningdjango_prod&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATABASE_PASSWORD&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;123;)&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATABASE_HOST&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;127.0.0.1&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATABASE_PORT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Email Server configuration&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMAIL_USE_TLS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMAIL_HOST&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;smtp.gmail.com&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMAIL_HOST_USER&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;mojekonto@gmail.com&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMAIL_HOST_PASSWORD&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;123;)&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMAIL_PORT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;587&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Local time zone for this installation. Choices can be found here:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# although not all choices may be available on all operating systems.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# If running in a Windows environment this must be set to the same as your&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# system time zone.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;TIME_ZONE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;America/Chicago&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Language code for this installation. All choices can be found here:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# http://www.i18nguy.com/unicode/language-identifiers.html&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;LANGUAGE_CODE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;en-us&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;SITE_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# If you set this to False, Django will make some optimizations so as not&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# to load the internationalization machinery.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;USE_I18N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Absolute path to the directory that holds media.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Example: &amp;quot;/home/media/media.lawrence.com/&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MEDIA_ROOT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/home/andrzejsliwa/webapps/learningdjango/public/media/&amp;quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# URL that handles the media served from MEDIA_ROOT. Make sure to use a&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# trailing slash if there is a path component (optional in other cases).&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Examples: &amp;quot;http://media.lawrence.com&amp;quot;, &amp;quot;http://example.com/media/&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;MEDIA_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;http://learningdjango.pl/media/&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;LOGIN_REDIRECT_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# trailing slash.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Examples: &amp;quot;http://foo.com/media/&amp;quot;, &amp;quot;/media/&amp;quot;.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ADMIN_MEDIA_PREFIX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;/admin_media/&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Make this unique, and don&amp;#39;t share it with anybody.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SECRET_KEY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;3x%axew739n_qae5g^cofle)#row(pl+zb&amp;amp;*42%bw&amp;amp;a#@_ccxc&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# List of callables that know how to import templates from various sources.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;TEMPLATE_LOADERS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.template.loaders.filesystem.load_template_source&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.template.loaders.app_directories.load_template_source&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#     &amp;#39;django.template.loaders.eggs.load_template_source&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;MIDDLEWARE_CLASSES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.middleware.common.CommonMiddleware&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.sessions.middleware.SessionMiddleware&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.auth.middleware.AuthenticationMiddleware&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ROOT_URLCONF&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;learningdjango.urls&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;TEMPLATE_DIRS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Put strings here, like &amp;quot;/home/html/django_templates&amp;quot; or &amp;quot;C:/www/django/templates&amp;quot;.&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Always use forward slashes, even on Windows.&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Don&amp;#39;t forget to use absolute paths, not relative paths.&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;/home/andrzejsliwa/webapps/learningdjango/learningdjango/templates&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.auth&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.contenttypes&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.sessions&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.sites&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.admindocs&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.admin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;django_extensions&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;south&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;local_settings&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Dzieki wyżej wymienionym poleceniom nadpiszemy naszą konfiguracje produkcyjną ustawieniami developerskimi.&lt;/p&gt;

&lt;p&gt;Na tym etapie również zabezpieczamy wyniki naszej pracy:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;git add .
git commit -m &lt;span class=&quot;s2&quot;&gt;&amp;quot;initial config.&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie tworzymy przykładowy plik &lt;code&gt;local_settings.py.example&lt;/code&gt; który wygląda następująco&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;here&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abspath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;DEBUG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;TEMPLATE_DEBUG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DEBUG&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;DATABASE_ENGINE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;postgresql_psycopg2&amp;#39;&lt;/span&gt; 
&lt;span class=&quot;n&quot;&gt;DATABASE_NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;learningdjango_dev&amp;#39;&lt;/span&gt;    
&lt;span class=&quot;n&quot;&gt;DATABASE_USER&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;postgres&amp;#39;&lt;/span&gt;              
&lt;span class=&quot;n&quot;&gt;DATABASE_PASSWORD&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;                  
&lt;span class=&quot;n&quot;&gt;DATABASE_HOST&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;                      
&lt;span class=&quot;n&quot;&gt;DATABASE_PORT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;                      

&lt;span class=&quot;n&quot;&gt;MEDIA_ROOT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;here&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;media&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;MEDIA_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;http://localhost/media/&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;TEMPLATE_DIRS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;here&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;templates&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;W pliku tym nadpisujemy ustawienia produkcyjne pliku konfiguracyjnego, oraz plik ten dodajemy do naszego repozytorium jako plik wzorcowy konfiguracji developerskiej ustawień:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add local_settings.py.example
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit -m &lt;span class=&quot;s2&quot;&gt;&amp;quot;added local_settings example&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Następnie przechodzimy do konfiguracji pliku &lt;code&gt;urls.py&lt;/code&gt; który powinien wyglądać następująco&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;django.conf.urls.defaults&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Uncomment the next two lines to enable the admin:&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;django.contrib&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;admin&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;admin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;autodiscover&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;urlpatterns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;patterns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Example:&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# (r&amp;#39;^learningdjango/&amp;#39;, include(&amp;#39;learningdjango.foo.urls&amp;#39;)),&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Uncomment the admin/doc line below and add &amp;#39;django.contrib.admindocs&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# to INSTALLED_APPS to enable admin documentation:&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;r&amp;#39;^admin/doc/&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;django.contrib.admindocs.urls&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Uncomment the next line to enable the admin:&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;r&amp;#39;^admin/&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;admin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;local_urls&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Również w pliku urls.py korzystamy z możliwości nadpisania konfiguracji produkcyjnej za pomocą pliku &lt;code&gt;local_urls.py&lt;/code&gt;, w tym celu tworzymy przykładowy plik konfiguracji developerskiej:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;django.conf.urls.defaults&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;learningdjango.urls&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urlpatterns&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;here&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abspath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;urlpatterns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;patterns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;django.views&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;r&amp;quot;^media/(?P&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;, &amp;quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;serve&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;, { &amp;quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document_root&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;: here(&amp;#39;media&amp;#39;),})&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;plik ten dodajemy do naszego repozytorium jako plik wzorcowy konfiguracji developerskiej ustawień:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add local_urls.py.example
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit -m &lt;span class=&quot;s2&quot;&gt;&amp;quot;added urls example&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Na tym etapie możemy zakończyć pracę nad konfiguracją wracając do głównego brancha i mergując zmiany (takie podejście do pracy z lokalnymi branchami jest podejściem zalecanym.)&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git checkout master
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git merge first_configuration
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Ostatnią czynnością przed uruchomieniem naszego skonfigurowanego projektu jest skopiowanie przykładów konfiguracji developerskiej tak by zostały one wczytane podczas uruchomienia (ponieważ nazwy tych plików są ignorowane nie ma obawy że trafią na serwer produkcyjny)&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;cp local_settings.py.example local_settings.py
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;cp local_urls.py.example local_urls.py
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;W tym momencie możemy uruchomić nasz testowy projekt&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./manage.py syncdb
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./manage.py runserver
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;W oknie przeglądarki możemy spróbować otworzyć słynny panel administracyjny django&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:8000/admin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Na zakończenie dzisiejszego odcinka przygód z Django, przedstawię również przykładowy skrypt instalacyjny dla naszej aplikacji na serwerach hostingu webfaction, plik ten nosi nazwę &lt;code&gt;fabfile.py&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;c&quot;&gt;# globals&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;learningdjango&amp;#39;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# enviroments&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;prod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Use the production server&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fab_hosts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;learningdjango.pl&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fab_user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;andrzejsliwa&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# git configuration&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;git_server&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;mygitserver&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;git_user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;git&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;git_user_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;my@mail.com&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;git_user_email&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;Andrzej Sliwa&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# destination configuration&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remote_destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;~/webapps/$(app_name)&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remote_sitepackages_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;$(remote_destination)/lib/python2.5&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remote_app_config_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;$(remote_destination)/$(app_name)/apache&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remote_apache_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;$(remote_destination)/apache2&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# tasks&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Run the test suite and bail out if it fails&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;./manage.py test&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;abort&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Prepare setup for deployment.&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;mkdir -p $(remote_destination)/public/media&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;ln -s $(remote_sitepackages_path)/django/contrib/admin/media $(remote_destination)/public/media/admin&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;cd $(remote_destination); git clone $(git_user)@$(git_server):$(app_name).git&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;git config --global user.email &amp;quot;$(git_user_email)&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;git config --global user.name &amp;quot;$(git_user_name)&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;easy_install-2.5 south&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;easy_install-2.5 django-debug-toolbar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;easy_install-2.5 django-extensions&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;copy_app_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;copy_app_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Copy all deployment configuration files.&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;cp $(remote_app_config_dir)/$(app_name).conf $(remote_apache_dir)/conf/httpd.conf&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;cp $(remote_app_config_dir)/$(app_name).wsgi $(remote_destination)/$(app_name).wsgi&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;cp $(remote_app_config_dir)/robots.txt $(remote_destination)/robots.txt&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Restart apache server&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;$(remote_apache_dir)/bin/restart&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Stop apache server&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;$(remote_apache_dir)/bin/stop&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Start apache server&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;$(remote_destination)/apache2/bin/start&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;migrate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Run migrations&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;cd $(remote_destination)/$(app_name); python2.5 manage.py syncdb &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rollback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Rollback last changes.&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;cd $(app_path); git checkout HEAD~1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;copy_app_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;deploy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Deploy current code on server.&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;fab_hosts&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;provided_by&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;git push&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;cd $(remote_destination)/$(app_name); git stash; git stash clear; git checkout master; git pull&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;copy_app_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debugoff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;debugon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Turn debug mode on&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;fab_hosts&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;provided_by&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;cd $(remote_destination)/$(app_name); sed -i -e &amp;#39;s/DEBUG = .*/DEBUG = True/&amp;#39; settings.py&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;debugoff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Turn debug mode off&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;fab_hosts&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;provided_by&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;cd $(remote_destination)/$(app_name); sed -i -e &amp;#39;s/DEBUG = .*/DEBUG = False/&amp;#39; settings.py&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;access_log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Show latest 100 lines of access log&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;tail -n 100 $(remote_apache_dir)/logs/access_log&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;error_log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;Show latest 100 lines of error log&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;tail -n 100 $(remote_apache_dir)/logs/error_log&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Uzupełenieniem konfiguracji wymaganej przez plik instalacji są pliki (&lt;code&gt;learningdjango.conf&lt;/code&gt;, &lt;code&gt;learningdjango.wsgi&lt;/code&gt;, &lt;code&gt;robots.txt&lt;/code&gt;) znajdujące się w katalogu apache w projekcie naszej aplikacji:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;tree learningdjango
learningdjango
|-- __init__.py
|-- apache
|   |-- robots.txt
|   |-- learningdjango.conf
|   &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;-- learningdjango.wsgi
|-- fabfile.py
|-- local_settings.py
|-- local_settings.py.example
|-- local_urls.py
|-- local_urls.py.example
|-- manage.py
|-- settings.py
&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;-- urls.py
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Plik &lt;code&gt;learningdjango.conf&lt;/code&gt; zawiera:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;ServerRoot &lt;span class=&quot;s2&quot;&gt;&amp;quot;/home/andrzejsliwa/webapps/starface/apache2&amp;quot;&lt;/span&gt;
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule wsgi_module modules/mod_wsgi.s
SetHandle

ServerRoot &lt;span class=&quot;s2&quot;&gt;&amp;quot;/home/andrzejsliwa/webapps/learningdjango/apache2&amp;quot;&lt;/span&gt;
LoadModule dir_module modules/mod_dir.so
LoadModule env_module modules/mod_env.so
LoadModule alias_module modules/mod_alias.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule mime_module modules/mod_mime.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule wsgi_module modules/mod_wsgi.so

KeepAlive Off
Listen 10753
LogFormat &lt;span class=&quot;s2&quot;&gt;&amp;quot;%{X-Forwarded-For}i %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b \&amp;quot;%{Referer}i\&amp;quot; \&amp;quot;%{User-Agent}i\&amp;quot;&amp;quot;&lt;/span&gt; combined
CustomLog logs/access_log combined
ServerLimit 2

&amp;lt;Location &lt;span class=&quot;s2&quot;&gt;&amp;quot;/robots.txt&amp;quot;&lt;/span&gt;&amp;gt;
    SetHandler None
&amp;lt;/Location&amp;gt;

&amp;lt;Location &lt;span class=&quot;s2&quot;&gt;&amp;quot;/admin_media&amp;quot;&lt;/span&gt;&amp;gt;
    SetHandler default
&amp;lt;/Location&amp;gt;

&amp;lt;Location &lt;span class=&quot;s2&quot;&gt;&amp;quot;/media&amp;quot;&lt;/span&gt;&amp;gt;
    SetHandler none
&amp;lt;/Location&amp;gt;

Alias /media /home/andrzejsliwa/webapps/learningdjango/public/media
Alias /admin_media /home/andrzejsliwa/webapps/learningdjango/lib/python2.5/django/contrib/admin/media
Alias /robots.txt /home/andrzejsliwa/webapps/learningdjango/robots.txt
WSGIScriptAlias / /home/andrzejsliwa/webapps/learningdjango/learningdjango.wsgi
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Plik &lt;code&gt;learningdjango.wsgi&lt;/code&gt; zawiera:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;                                                                                                                                         

&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;/home/andrzejsliwa/webapps/learningdjango&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;/home/andrzejsliwa/webapps/learningdjango/lib/python2.5&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;django.core.handlers.wsgi&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WSGIHandler&lt;/span&gt;                                                                                                  

&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;DJANGO_SETTINGS_MODULE&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;learningdjango.settings&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;application&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WSGIHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Plik &lt;code&gt;robots.txt&lt;/code&gt; zabezpiecza nas przed niechcianym indeksowaniem naszej nie ukonczonej jeszcze aplikacji:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;User-agent: * Disallow: /
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Wyżej zaprezentowana konfiguracja pozwala na wygodne skonfigurowanie i przeprowadzenie wdrożenia aplikacji:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;fab prod setup
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;fab prod deploy
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Wyżej prezentowane pliki i konfiguracje nie stanowią oczywiście w pełni gotowego rozwiązania, stanowią jedynie przykład syntezy zalecanych rozwiązań znalezionych w dokumentacji projektów i przykładach wykorzystania. Mogą stanowić dobrą bazę do dalszej pracy nad aplikacją, środowiskiem programistycznym i produkcyjnym.&lt;/p&gt;

&lt;p&gt;W następnym poście postaram się zaprezentować podstawy tworzenia aplikacji wraz z wykorzystaniem najciekawszych rozszerzeń środowiska programistycznego Django.&lt;/p&gt;
</content>
   <updated>2009-09-18T00:00:00-07:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="django" label="django" />
   <updated>2009-09-18T00:00:00-07:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="python" label="python" />
   <updated>2009-09-18T00:00:00-07:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="git" label="git" />
   <updated>2009-09-18T00:00:00-07:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="macports" label="macports" />
   <updated>2009-09-18T00:00:00-07:00</updated>
   <category scheme="http://andrzejsliwa.com/" term="osx" label="osx" />
 </entry>
 
</feed>