<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Prskavčí blog]]></title>
  
  <link href="http://blog.prskavec.net//" />
  <updated>2012-05-07T09:47:39+02:00</updated>
  <id>http://blog.prskavec.net//</id>
  <author>
    <name><![CDATA[Ladislav Prskavec]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/prskavec" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="prskavec" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">prskavec</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><entry>
    <title type="html"><![CDATA[Angular Meetup v Praze]]></title>
    <link href="http://blog.prskavec.net//2012/05/angular-meetup-v-praze/" />
    <updated>2012-05-07T09:23:00+02:00</updated>
    <id>http://blog.prskavec.net//2012/05/angular-meetup-v-praze</id>
    <content type="html"><![CDATA[<h1>AngularJS Meetup proběhl v Praze</h1>

<p>Dne 4.5.2012 16-21h proběhl meetup přiznivců <a href="http://www.angularjs.org">AngularJS</a> v Hub Praha na Smíchově. Po <a href="http://www.meetup.com/AngularJS-NYC/events/63007142/">New Yorku</a> a <a href="http://www.meetup.com/AngularJS-MTV/events/62918252/">Mountain View</a> byla Praha doufám třetí na světě kde se něco takového konalo. Angular tým <a href="https://twitter.com/#!/mhevery">Misko Hevery</a>, <a href="https://twitter.com/#!/IgorMinar/">Igor Minar</a>, <a href="https://twitter.com/#!/vojtajina/">Vojta Jína</a> nám dělali podporu a to Vojta dokonce osobně v Praze. Přes hangout jsme pozdravili i zbytek týmu.</p>

<p>Pár fotek z <a href="https://plus.google.com/photos/113391188023467233438/albums/5738773000511139121">mobilu</a> z akce je k dispozici.</p>

<p>Celá akce byla postavená na dotazech a společné práci nad vlastními projekty nebo nad ukázkovou aplikací <a href="http://docs.angularjs.org/tutorial/">angular-phonecat</a>. K dipozici byl bar s občerstvením a celá doba uběhla velmi rychle. S probíraných věcí mi asi nejvíce utkvěli informace o <a href="http://stackoverflow.com/questions/9682092/databinding-in-angularjs">dirtycheckingu</a> co nám Vojta vyložil.</p>

<p>Každopádně celá akce byla super a doufám, že ji zoopakujeme někdy brzo znovu a nemusíme se zaměřovat jen na AngularJS, ale na programování v Javascriptu obecně.</p>

<p>Napište do komentářů kam by jste chtěli, aby se meetupy ubírali.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[AngularJS v Praze]]></title>
    <link href="http://blog.prskavec.net//2012/03/angularjs-v-praze/" />
    <updated>2012-03-27T05:50:00+02:00</updated>
    <id>http://blog.prskavec.net//2012/03/angularjs-v-praze</id>
    <content type="html"><![CDATA[<p><a href="http://angularjs.org">AngularJS</a> je MVC javascriptový framework, opensource, podporovaný firmou Google. Jeden z hlavních vývojářů je <a href="http://twitter.com/#!/vojtajina">Vojta Jína</a>, který v dubnu/květnu bude v Praze a potřebujeme zjistit zda by byl zájem o něco více než jenom přednášku co bude v rámci.</p>

<p>2.5. Vojta Jina - Google Mountain View USA. Introduction to Angular. Vojta is a developer in Google actively developing a Javascript architecture Angular. <a href="http://www.eclub.cvutmedialab.cz/">eClubu</a></p>

<p>4.5. hacking party sponzored by Google - <a href="http://srazy.info/angularjs-meetup/2164">meetup</a></p>

<p>Díky všem za vyplnění a bude vás informovat, sledujte <a href="http://twitter.com/#!/abtris">@abtris</a> a <a href="http://twitter.com/#!/vojtajina">@vojtajina</a> na twitteru a dozvíte se vše.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Jak snadno pracovat s CSS sprites]]></title>
    <link href="http://blog.prskavec.net//2012/03/jak-snadno-pracovat-s-css-sprites/" />
    <updated>2012-03-01T22:00:00+01:00</updated>
    <id>http://blog.prskavec.net//2012/03/jak-snadno-pracovat-s-css-sprites</id>
    <content type="html"><![CDATA[<blockquote><p>CSS spirty představují způsob, jak snížit počet HTTP požadavků, které klient vyšle k získání prvků obsažených na stránce. Obrázky se sloučí do jednoho většího a umístí se na určených X,Y souřadnicích. Pak pomocí CSS atributu background-position můžeme nastavit vzniklý obrázek na pozadí různým elementům stránky a pomocí dalších CSS vlastností umístíme pozadí tak, aby požadovaný jednotlivý obrázek padl do viditelné oblasti elementu na stránce.</p><footer><strong>cs.spritegen.website-performance.org</strong> <cite><a href='http://cs.spritegen.website-performance.org/section/what-are-css-sprites/'>Co Jsou CSS Sprites?</a></cite></footer></blockquote>


<p>Poslouchal jsem <a href="http://official.fm/tracks/352028">podcast</a> s <a href="http://vaclav.vancura.org">Vaškem Vančurou</a>, kde popisuje svoji práci s LESS a sprites pomocí software <a href="http://www.texturepacker.com/">TexturePacker</a>.</p>

<p>Zkoušel jsem Vaška přemluvit, aby něco napsal:</p>

<blockquote><p>@vancura Me se to libilo, taky jsem si zavzpominal. Ale o tom jak pouzivas LESS a sprites nechces o tom neco napsat s nejakym prikladem?<br/>@abtris Kdyby byl cas…</p><footer><strong>@vancura</strong> <cite><a href='https://twitter.com/vancura/status/175122362516258816'>twitter.com/vancura/status/&hellip;</a></cite></footer></blockquote>


<p>Ale nemá čas, tak jsem se rozhodl to udělat sám.</p>

<p>Zvolil jsem jednoduchou ukázku, stáhnul jsem <a href="http://wefunction.com/2008/07/function-free-icon-set/">sadu icon</a> a potom jsem zvolit v Texturepackeru data format css a přidal jsem adresář s iconami. Program automaticky vytvoří pomocí publish sprite.png a sprite.css.</p>

<p>Výsledek můžete vidět zde:</p>

<p><img class="center" src="http://blog.prskavec.net//assets/sprite.png"></p>

<p>a css kód:</p>

<figure class='code'><figcaption><span> (sprite.css)</span> <a href='http://blog.prskavec.net//downloads/code/sprite.css'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
<span class='line-number'>107</span>
<span class='line-number'>108</span>
<span class='line-number'>109</span>
<span class='line-number'>110</span>
<span class='line-number'>111</span>
<span class='line-number'>112</span>
<span class='line-number'>113</span>
<span class='line-number'>114</span>
<span class='line-number'>115</span>
<span class='line-number'>116</span>
<span class='line-number'>117</span>
<span class='line-number'>118</span>
<span class='line-number'>119</span>
<span class='line-number'>120</span>
<span class='line-number'>121</span>
<span class='line-number'>122</span>
<span class='line-number'>123</span>
<span class='line-number'>124</span>
<span class='line-number'>125</span>
<span class='line-number'>126</span>
<span class='line-number'>127</span>
<span class='line-number'>128</span>
<span class='line-number'>129</span>
<span class='line-number'>130</span>
<span class='line-number'>131</span>
<span class='line-number'>132</span>
<span class='line-number'>133</span>
<span class='line-number'>134</span>
<span class='line-number'>135</span>
<span class='line-number'>136</span>
<span class='line-number'>137</span>
<span class='line-number'>138</span>
<span class='line-number'>139</span>
<span class='line-number'>140</span>
<span class='line-number'>141</span>
<span class='line-number'>142</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="c">/* ----------------------------------------------------</span>
</span><span class='line'><span class="c">   created with http://www.texturepacker.com </span>
</span><span class='line'><span class="c">   ----------------------------------------------------</span>
</span><span class='line'><span class="c">   $TexturePacker:SmartUpdate:83a9321cb66d0d62791f1fdda5367522$</span>
</span><span class='line'><span class="c">   ----------------------------------------------------</span>
</span><span class='line'>
</span><span class='line'><span class="c">   usage: &lt;span class=&quot;{-spritename-} sprite&quot;&gt;&lt;/span&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="c">   replace {-spritename-} with the sprite you like to use</span>
</span><span class='line'>
</span><span class='line'><span class="c">*/</span>
</span><span class='line'>
</span><span class='line'><span class="nc">.sprite</span> <span class="p">{</span><span class="k">display</span><span class="o">:</span><span class="k">inline</span><span class="o">-</span><span class="k">block</span><span class="p">;</span> <span class="k">overflow</span><span class="o">:</span><span class="k">hidden</span><span class="p">;</span> <span class="k">background-repeat</span><span class="o">:</span> <span class="k">no-repeat</span><span class="p">;</span><span class="k">background-image</span><span class="o">:</span><span class="sx">url(sprite.png)</span><span class="p">;}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">.accepted_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-752px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.add_16</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">16px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">16px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-38px</span> <span class="m">-1002px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.add_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-702px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.app_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-652px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.arrow_down_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-602px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.arrow_down_green_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-552px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.arrow_left_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-952px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.arrow_left_green_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-902px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.arrow_right_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-852px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.arrow_right_green_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-802px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.arrow_up_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-752px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.arrow_up_green_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-702px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.beer_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-652px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.blinklist_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-602px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.blue_speech_bubble_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-552px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.book_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-452px</span> <span class="m">-502px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.box_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-402px</span> <span class="m">-502px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.box_download_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-352px</span> <span class="m">-502px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.box_upload_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-302px</span> <span class="m">-502px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.camera_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-252px</span> <span class="m">-502px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.camera_add_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-202px</span> <span class="m">-502px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.camera_delete_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-152px</span> <span class="m">-502px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.camera_noflash_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-102px</span> <span class="m">-502px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.camera_noflash_add_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-502px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.camera_noflash_delete_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-502px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.camera_noflash_warning_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-452px</span> <span class="m">-452px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.camera_warning_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-402px</span> <span class="m">-452px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.cancel_16</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">16px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">16px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-20px</span> <span class="m">-1002px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.cancel_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-352px</span> <span class="m">-452px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.cd_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-302px</span> <span class="m">-452px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.circle_blue</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-252px</span> <span class="m">-452px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.circle_green</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-202px</span> <span class="m">-452px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.circle_orange</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-152px</span> <span class="m">-452px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.circle_red</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-102px</span> <span class="m">-452px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.clock_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-452px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.coffee_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-452px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.coffee_mug</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-452px</span> <span class="m">-402px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.comment_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-402px</span> <span class="m">-402px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.comment_add_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-352px</span> <span class="m">-402px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.comment_remove_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-302px</span> <span class="m">-402px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.comment_warning_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-252px</span> <span class="m">-402px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.computer_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-202px</span> <span class="m">-402px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.creditcard_american_express</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-152px</span> <span class="m">-402px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.creditcard_cirrus</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-102px</span> <span class="m">-402px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.creditcard_mastercard</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-402px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.creditcard_paypal</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-402px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.creditcard_solo</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-452px</span> <span class="m">-352px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.creditcard_switch</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-402px</span> <span class="m">-352px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.creditcard_visa</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-352px</span> <span class="m">-352px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.cross_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-302px</span> <span class="m">-352px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.database_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-252px</span> <span class="m">-352px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.database_add_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-202px</span> <span class="m">-352px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.database_remove_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-152px</span> <span class="m">-352px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.database_warning_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-102px</span> <span class="m">-352px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.delicious_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-352px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.designfloat_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-352px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.digg_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-452px</span> <span class="m">-302px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.feedburner_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-402px</span> <span class="m">-302px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.flickr_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-352px</span> <span class="m">-302px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.floppy_disk_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-302px</span> <span class="m">-302px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.folder_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-252px</span> <span class="m">-302px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.folder_add_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-202px</span> <span class="m">-302px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.folder_delete_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-152px</span> <span class="m">-302px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.folder_warning_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-102px</span> <span class="m">-302px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.furl_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-302px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.globe_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-302px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.google_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-452px</span> <span class="m">-252px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.heart_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-402px</span> <span class="m">-252px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.home_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-352px</span> <span class="m">-252px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.image_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-302px</span> <span class="m">-252px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.image_add_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-252px</span> <span class="m">-252px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.image_delete_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-202px</span> <span class="m">-252px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.image_warning_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-152px</span> <span class="m">-252px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.lightbulb_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-102px</span> <span class="m">-252px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.lock_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-252px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.lock_open_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-252px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.mail_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-452px</span> <span class="m">-202px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.mail_add_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-402px</span> <span class="m">-202px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.mail_delete_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-352px</span> <span class="m">-202px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.mail_forward_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-302px</span> <span class="m">-202px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.mail_reply_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-252px</span> <span class="m">-202px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.mail_spam_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-202px</span> <span class="m">-202px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.mail_write_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-152px</span> <span class="m">-202px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.mixx_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-102px</span> <span class="m">-202px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.mouse_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-202px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.navigate_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-202px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.newspaper_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-452px</span> <span class="m">-152px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.paper</span><span class="o">&amp;</span><span class="nt">pencil_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-402px</span> <span class="m">-152px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.paper_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-352px</span> <span class="m">-152px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.paper_content_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-302px</span> <span class="m">-152px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.paper_content_chart_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-252px</span> <span class="m">-152px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.paper_content_pencil_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-202px</span> <span class="m">-152px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.pencil_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-152px</span> <span class="m">-152px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.pie_chart_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-102px</span> <span class="m">-152px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.printer_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-152px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.questionmark_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-152px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.reddit_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-452px</span> <span class="m">-102px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.refresh_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-402px</span> <span class="m">-102px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.rss_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">45px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">45px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-802px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.search_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-352px</span> <span class="m">-102px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.smile_grin_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-302px</span> <span class="m">-102px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.smile_sad_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-252px</span> <span class="m">-102px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.spanner_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-202px</span> <span class="m">-102px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.speech_bubble_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-152px</span> <span class="m">-102px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.star_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-102px</span> <span class="m">-102px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.star_half_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-102px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.star_off_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-102px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.sumbleupon_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-452px</span> <span class="m">-52px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.table_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-402px</span> <span class="m">-52px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.table_green_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-352px</span> <span class="m">-52px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.tabs_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-302px</span> <span class="m">-52px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.technorati_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-252px</span> <span class="m">-52px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.thumbs_down_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-202px</span> <span class="m">-52px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.thumbs_up_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-152px</span> <span class="m">-52px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.twitter_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-102px</span> <span class="m">-52px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.twitter_boxed_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-52px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.usb_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-52px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.user_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-452px</span> <span class="m">-2px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.user_add_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-402px</span> <span class="m">-2px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.user_delete_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-352px</span> <span class="m">-2px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.user_two_delete_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-302px</span> <span class="m">-2px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.user_warning_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-252px</span> <span class="m">-2px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.users_two_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-202px</span> <span class="m">-2px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.users_two_add_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-152px</span> <span class="m">-2px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.users_two_warning_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-102px</span> <span class="m">-2px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.warning_16</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">16px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">16px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-1002px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.warning_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-52px</span> <span class="m">-2px</span><span class="p">}</span>
</span><span class='line'><span class="nc">.yahoo_48</span> <span class="p">{</span><span class="k">width</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span><span class="m">48px</span><span class="p">;</span> <span class="k">background-position</span><span class="o">:</span> <span class="m">-2px</span> <span class="m">-2px</span><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Shrnutí</h2>

<p>Je to jen ukázka jak může tento program usnadnit práci, kterou jsem viděl obvykle dělat kodéry ve Photoshopu a pracně ručně nastavovat v CSS.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Barcamp Vsetín 2012 - Budou učebnice v budoucnosti jen elektronické?]]></title>
    <link href="http://blog.prskavec.net//2012/02/barcamp-vsetin-2012-budou-ucebnice-v-budoucnosti-jen-elektronicke/" />
    <updated>2012-02-05T08:03:00+01:00</updated>
    <id>http://blog.prskavec.net//2012/02/barcamp-vsetin-2012-budou-ucebnice-v-budoucnosti-jen-elektronicke</id>
    <content type="html"><![CDATA[<h2>Barcamp Vsetín 2012</h2>

<p>Letos jsem se poprvé dostal na Vsetínský Barcamp a spousta přednášek mi přišla zajímavá a z těch co jsem viděl mi nejlepší přišli <a href="https://twitter.com/nofreeusernames">Olga Biernátová</a> - Jak se uvádí bestseller na český trh a <a href="https://twitter.com/fdousek">Filip Doušek</a> - Hejno bez ptáků: Od 1500 myšlenek k románu. Zaujala mě iniciativa proti hernám <a href="http://www.mapyhazardu.cz/">http://www.mapyhazardu.cz/</a>, kde dělají v Brnění, o.s. užasnou práci.</p>

<p>Moje přednáška byla večer na střeše a sešla se nám malá skupina, kterou to zajímalo a hodně se diskutovalo a to mám na Barcampech rád.</p>

<h2>Budou učebnice  v budoucnosti jen elektronické?</h2>

<p>Elektronické knihy procházejí změnami, všichni si pamatují čtení v palm pilotech a jak to změnil Kindle, když přišel s prvním velkým obchodem s knihami. Sám jsem si tehdy Kindle 2 koupil a na beletrii neznám nic lepšího. Ale řešil jsem problém, že mám manuály a další odborné knihy převážně v PDF a to se na tom Kindlu nedalo moc dobře číst. Potom přišel iPad a iBook od Apple, tam se dají dobře číst i PDF, ale jinak to je stejné jako u kindle s nevýhodou toho, že to není elektronický inkoust.</p>

<h3>iBooks2</h3>

<p>Dne <a href="http://www.apple.com/pr/library/2012/01/19Apple-Reinvents-Textbooks-with-iBooks-2-for-iPad.html">19.2.2012 ohlásil</a>, že vymysleli jak dělat učebnice jinak a lépe. Pokud jste viděli ukázky z knihy <a href="http://itunes.apple.com/us/book/e.o.-wilsons-life-on-earth/id490270998?mt=13">Life Of Earth</a> zjistíte, že knihy mohou být úžasně inteaktivní. Přidali podporu videa, fotogalerie, 3D obrázků, HTML5 widgetů a dalších věcí, které ty knihy oživí. Pro beletrii to moc význam nemá, ale jistě se najdou autoři, kteří to využijí. Pro učebnice a odborné knihy to je ovšem úžasné. Na konci každé kapitoli, můžete přidat Review, kde vyzkoušíte čtenáře zda pochopil obsah kapitoli a on získá zpětnou vazbu, která mu při pasivním čtení chybí. Do knih si můžete dělat poznámky a zvýrazňovat zajímavé pasáže což mnozí studenti rádi využijí.</p>

<h3>iBooks Author</h3>

<p>Kromě iBooks2 aplikace, ale největší přínos je v tom, že Apple vydal aplikaci v které si zdarma takovou knihu můžete vytvořit. Na Mac je tato aplikace prostě úžasná, zcela ve stylu nástrojů iWork a každý průměrný uživatel si lehce vytvoří co chce.</p>

<p><img class="center" src="http://blog.prskavec.net//assets/svnbook.jpg" title="'SVN kniha v iBook Author'" ></p>

<p>Já jsem si více hrál s HTML5 widgety, pomocí, kterých se dájí možnosti rozšiřovat a také jsem řešil jak sázet matematiku. Matematiku dostanete do iBooks Author podobně jako do iWork například pomocí <a href="http://www.dessci.com/en/products/MathType_Mac/">MathType</a> nebo <a href="http://www.chachatelier.fr/latexit/">LaTeXiT</a>.</p>

<p>HTML5 widgety můžete vyrobit sami nebo pomocí nějakého nástroje:</p>

<ul>
<li><a href="https://developer.apple.com/library/mac/#documentation/AppleApplications/Conceptual/Dashcode_UserGuide/Contents/Resources/en.lproj/Introduction/Introduction.html">DashCode</a> - součást Mac OS X</li>
<li><a href="http://labs.adobe.com/technologies/edge/">Adobe Edge</a> - v současné době betaverze</li>
<li><a href="http://www.sencha.com/products/animator">Sencha Animator</a></li>
<li><a href="http://tumultco.com/hype/">Tumult Hype</a></li>
</ul>


<p>další zajímavé widgety můžete najít na internetu, například jsem našel na <a href="http://www.panophoto.org/forums/viewtopic.php?f=64&amp;t=10417&amp;p=158330#p158423">panoramatické prohlížení fotek</a>.</p>

<p>Widgety mají omezení, <em>nemohou přistupovat na disk a k internetu</em>.</p>

<h3>iBookstore</h3>

<p>Pokud projedete celou výrobou knihy je potřeba ji dostat do iBookstore. Nejdříve se musíte zaregistrovat jako autor a potom si můžete stáhnout program iTunes Producer, pomocí, kterého můžete dílo uploadnout do iBookstore.</p>

<p><img class="center" src="http://blog.prskavec.net//assets/itunesproducer.jpg" title="'iTunesProducer'" ></p>

<p>Jak je vidět na obrázku musíte vyplňit povinné údaje. Ve výběru jazyka není čeština k dispozici. Ale napište <strong>cze</strong> a kniha v češtině projde. Screenshoty ke knize udělejte přímo na iPadu, aby měli správné rozlišení a exportujte je jako <strong>JPG</strong>.</p>

<p>Po tom co nahrajete knihu pres iTunes producer a Apple ji schválí (cca 1 týden), můžete přes iTunes Connect sledovat statistiky jak se kniha stahuje po celém světě.</p>

<p><img class="center" src="http://blog.prskavec.net//assets/sales_and_trends1.jpg" title="'iTunesConnect'" ></p>

<p><img class="center" src="http://blog.prskavec.net//assets/sales_and_trends2.jpg" title="'iTunesConnect2'" ></p>

<p>Jako asi <a href="http://itunes.apple.com/cz/book/subversion/id498008712?mt=11">první česká kniha ve formátu</a> iBooks2 stažená více jak 15 kusů je vlastně bestseller jak říkala ve své přednášce Olga.</p>

<p><img class="center" src="http://blog.prskavec.net//assets/cite-nofreeusernames.jpg" title="'cite barcamp vsetin 2012'" ></p>

<h3>Závěr</h3>

<p>Určitě chci doporučit pokud chcete knihu vydat sami, tohle je cesta. Sice je omezené na iBookstore a případně můžete v PDF si to vydat někde jinde, ale přidaná hodnota interaktivní učebnice určitě stojí za to. Pro beletrii bych asi volil stále osvěčenou metodu klasického formátu pro více zařízení, ale můžete to vylepšit i tam asi závisí na autorovy. Knihu můžete formátovat na výšku a na šířku a může vypadat pokaždé úplně jinak. Pokud budete mít typy na widgety, zkuste je uvést v komentářích. Mě napadlo, že by bylo dobré udělat widget na zdrojové kódy, kde by šlo prohlížet prsty, byla by zvýrazněná syntaxe atd.</p>

<p>Celý Barcamp ve Vsetíně byl skvělá akce a děkuji organizátorům za letošní ročník.</p>

<h3>Video z přednášky</h3>

<iframe src="http://player.vimeo.com/video/36430257?title=0&amp;byline=0&amp;portrait=0" width="400" height="225" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>


<p><a href="http://vimeo.com/36430257">Ladislav Prskavec</a> from <a href="http://vimeo.com/user3006694">Michal Berg</a> on <a href="http://vimeo.com">Vimeo</a>.</p>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Jenkins – použití Continuous Integration engine pro PHP]]></title>
    <link href="http://blog.prskavec.net//2011/11/jenkins-pouziti-continuous-integration-engine-pro-php/" />
    <updated>2011-11-24T20:24:00+01:00</updated>
    <id>http://blog.prskavec.net//2011/11/jenkins-pouziti-continuous-integration-engine-pro-php</id>
    <content type="html"><![CDATA[<p>Vyvíjíte větší PHP projekt a potřebujete zlepšit koordinaci vašeho týmu a vaše softwarové procesy? Přístup Continuous Integration a nástroj Jenkins, který jej umožňuje implementovat, vám pomohou. Dozvíte se, jak Jenkins nainstalovat, jak ověřovat kvalitu softwarového produktu, jak řešit spouštění automatických testů, jak testovat coding standard, jaké si stanovovat softwarové metriky či jak kontinuálně deployovat vaše průběžné výsledky.</p>

<p>Všechno ukazuji na praktických příkladech s pomocí Ubuntu a virtualizace (VirtualBox) a za použití nástroje <a href="http://www.vagrantup.com">Vagrant</a>.</p>

<h2>Osnova školení pro <a href="http://webexpo.cz/blog/#prskavec">WebExpo Academy</a></h2>

<ul>
<li>Automatizace buildu</li>
<li>Instalace Jenkins</li>
<li>Continuous Integration</li>
<li>Continuous Inspection

<ul>
<li>API dokumentace</li>
<li>Softwarove metriky</li>
<li>Duplicitni kod</li>
<li>Coding standard</li>
<li>Agregace vysledku</li>
</ul>
</li>
<li>Automatizace automatizace</li>
<li>Continuous Delivery</li>
</ul>


<h2>Informace o školení</h2>

<p>Termín: pátek 16. 12. 2011 10:00 – 18:00</p>

<p>Cena 4 490,- Kč. V prosinci jen za 2 290,- Kč!</p>

<p>Kapacita: Zbývají 2 místa.</p>

<p>Objednávky: <a href="mailto:academy@webexpo.net">academy@webexpo.net</a>, +420 775 477 457</p>

<p>Školení se konají v Praze v prostoru WebHub, adresa: Kafkova 16, Praha 6, dvě minuty pěšky od metra Dejvická.</p>

<h2>Související články</h2>

<ul>
<li><a href="http://blog.prskavec.net/2009/12/php-codebrowser/">http://blog.prskavec.net/2009/12/php-codebrowser/</a></li>
<li><a href="http://blog.prskavec.net/2009/02/hudson-a-php/">http://blog.prskavec.net/2009/02/hudson-a-php/</a></li>
<li><a href="http://blog.prskavec.net/2009/04/phphudson/">http://blog.prskavec.net/2009/04/phphudson/</a></li>
<li><a href="http://blog.prskavec.net/2009/03/pdepend-a-php-frameworky/">http://blog.prskavec.net/2009/03/pdepend-a-php-frameworky/</a></li>
<li><a href="http://blog.prskavec.net/2009/03/pdepend-a-php-frameworky-dodatek/">http://blog.prskavec.net/2009/03/pdepend-a-php-frameworky-dodatek/</a></li>
<li><a href="http://blog.prskavec.net/2008/11/phpundercontrol-vs-xinc/">http://blog.prskavec.net/2008/11/phpundercontrol-vs-xinc/</a></li>
<li><a href="http://blog.prskavec.net/2008/06/phing-svnlogtask/">http://blog.prskavec.net/2008/06/phing-svnlogtask/</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Průřez historií verzovacích systémů]]></title>
    <link href="http://blog.prskavec.net//2011/10/prurez-historii-verzovacich-systemu/" />
    <updated>2011-10-31T06:42:00+01:00</updated>
    <id>http://blog.prskavec.net//2011/10/prurez-historii-verzovacich-systemu</id>
    <content type="html"><![CDATA[<iframe src="http://player.vimeo.com/video/31341006?title=0&amp;byline=0&amp;portrait=0&amp;color=ffffff" width="430" height="242" frameborder="0" webkitAllowFullScreen allowFullScreen></iframe>


<p>Na videu je vidět průřez časovou osou jak čas běžel a jaké verzovací systémy nám postupně vznikali a vznikají.</p>

<p>Verzovací systémy jsou tu od roku 1972. Source Code Control System (SCCS) byl první verzovací systém, který položil základ všem verzovacím systémům až po dodnes.
Dnes jsou nejznámější systémy: Subversion, Git a Mercurial. Ale každý měl nějaké předchůdce a vznikl protože ty předchozí nevyhovovali.</p>

<p>SCCS byl komerční a nahradil ho později Revision Control System (RCS), který byl open source náhradou za SCCS, na jeho základech byl v roce 1990 vytvořen Concurrent Versions System (CVS), který většina vývojářů už zná. Mezi jeho hlavní nevýhody jsem vždy považoval nemožnost přejmenování adresářů a správu jednotlivých souborů. Subversion v roce 2000 přišel s novinkou ve verzovaní celého stromu adresářů. Atomicita operací se rozšířila na celé adresáře ne jen na soubory jako v CVS. Subversion podporuje attributy, které se přidávání k souborů a s těmito metadaty dále pracuje.</p>

<p>SCCS ale kromě verzovacích systémů, které mají architekturu klient server byl také předchůdcem distribuovaných verzovacích systémů. První distribuovaný verzovací systém byl v roce 1996 Sun WorkShop TeamWare. Larry McVoy, který navrhl TeamWare vytvořil později BitKeeper, který se používal do roku 2005 pro vývoj jádra linuxu. V roce 2005 po sporu mezi společností BitKeeper a komunitou, přestali poskytovat zdarma BitKeeper a tak se Linus Torvalds rozhodl začít s vlastním verzovacím systémem Git. Na stejnou věc reagoval i Matt Mackall, když o měsíc později po Gitu uvedl Mercurial.</p>

<p>Verzovacích systémů je samozřejmě desítky, stále vznikají nové a spousta jich žije i když je asi dost lidí ani nezná. Nedají se vyzkoušet všechny. Osobně mám nejvíce zkušeností s tím čím jsem si prošel v práci a to je CVS, SVN a Git. Za ty roky co s nimi pracuji si myslím, že jsem si vždy polepšil a uvidíme co bude dál. Dnes považuji Git za naprosto dostačující k mé práci, jediné co bych mu vytknul je verze pro windows, kde často řeším problémy, které na linuxu ani neexistují.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Motivace a Verzovací systémy]]></title>
    <link href="http://blog.prskavec.net//2011/10/motivace-a-vcs/" />
    <updated>2011-10-26T20:12:00+02:00</updated>
    <id>http://blog.prskavec.net//2011/10/motivace-a-vcs</id>
    <content type="html"><![CDATA[<h2>Proč bychom potřebovali verzovací systém?</h2>

<p>Toto je častá otázka, kterou slyším. Spousta lidí používá sdílené adresáře pro práci s dokumenty. Přejmenovávají soubory a adresáře. Pokud znáte dokumenty typu Projekt-Final-Update!!.doc apod. tak víte o čem mluvím.</p>

<h2>Každý programátor pracuje v jiné podadresáři?</h2>

<p>Tak to trochu může lidem připadat, ale programátoři používají verzovací systém, který dokumentovou databází, která sleduje změny a pomůže v mnoha věcech.</p>

<h3>Záloha a Obnova</h3>

<p>Soubory, které ukládáme do verzovacího systému si nesou infomaci o času uložení a není problém skočit v čase co existuje repozitář kam chcete třeba co jste dělali 29.7.2009? Není problém.</p>

<h3>Synchronizace</h3>

<p>Pokud si verzujete například konfiguraci nastavení linuxu. Příklady najdete na githubu v repositářích nazvaných <a href="https://github.com/search?type=Repositories&amp;language=&amp;q=dotfiles&amp;repo=&amp;langOverride=&amp;x=16&amp;y=29&amp;start_value=1">dotfiles</a>. Tak si pomocí verzovacího systému lehce udržujete konfiguraci na všech počítačích, které používáte. Obdobně není problém to dělat s jakýmikoliv dokumenty.</p>

<h3>Jednoduché Undo</h3>

<p>Modifikujete soubor a nefunguje to a potřebujete vrátit změny zpět. Není problém obnovit poslední dobrou verzi. Maličkost.</p>

<h3>Undo</h3>

<p>Kdykoliv máte k dispozici undo, pokud například najdete chybu, kterou jste udělali před rokem není problém se vrátit zpět a podívat se jaké změny jste dělali a proč.</p>

<h3>Sledování změn</h3>

<p>Soubory jsem změněny, ale verzovací systém uchovává také zprávu, kde se často vysvětluje proč změna byla udělaná, dost často obsahuje například odkaz do bug trackeru apod. To jsou věci, které se často ze samotných souborů vyčíst nedají.</p>

<h3>Sledování vlastníka</h3>

<p>Každá změna je podepsaná a můžete kdykoliv zjistit, kdo který řádek modifikoval. To se hodí pokud potřebujete zjistit kdo změnu udělal.</p>

<h3>Pískoviště (sandbox)</h3>

<p>Výhoda verzovacích systémů je právě, že můžete pracovat na velkých změnách v izolované oblasti bez toho aby jste se báli, že ovlivníte celek.</p>

<h3>Větve a merge</h3>

<p>Větve slouží jako velké pískoviště, můžete mít desítky větví, které mohou po dlouhou dobu fungovat izolovaně a později pokud budete chtít spojíte (merge) je kam potřebujete.</p>

<h3>Závěr</h3>

<p>Sdílené adresáře jsou rychlé a jednoduché, ale rozhodně tyto vlastnosti verzovacích systémů jsou něco co je o dost lepší.</p>

<p>Verzovacích systémů jsou desítky, od SCCS (1972), přes CVS (1990), Subversion (2000) k distribuovaným jako je Darcs (2002), Git (2005) nebo Mercurial (2005). K nejnovějším přírůstkům patří Verocity (2011), které přidává například přímo podporu SCRUMu.</p>

<p>Volbu nechám na vás u mě od roku 2009 <a href="http://blog.prskavec.net/2009/11/proc-jsem-presel-z-mercurial-na-git/">vítězí Git</a> a ani za 2 roky se v tom nic nezměnilo.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Google Developer Day 2011]]></title>
    <link href="http://blog.prskavec.net//2011/10/google-developer-day-2011/" />
    <updated>2011-10-18T09:01:00+02:00</updated>
    <id>http://blog.prskavec.net//2011/10/google-developer-day-2011</id>
    <content type="html"><![CDATA[<p>GDD již tradičně v Clarionu, registrace se dneska pěkně protáhla pokud jste nepřišli včas a nevyužili některé jiné fronty než té první.</p>

<p>Reportáž online:</p>

<h2>Keynote</h2>

<p>9:09 Sedíme na keynote a uvidíme co se chystá ….</p>

<p><a href="https://developers.google.com/go/stories">Video na začátku</a> a potom Filip pokračuje v Keynote.</p>

<p>9:19 Brad Abrams - Google Plus Platform
Zatím se probíráme od roku 1990 do součastnosti naší minulostí a přesouváme se k mobile a cloud.
Aktivace telefonů s Androidem mezi únorem 2010 (60k) až k 550k v červenci 2011. 300k aplikací v Android Marketu.</p>

<p>9:35 Petr Nálevka - <a href="https://market.android.com/details?id=com.urbandroid.sleep&amp;hl=cs">Sleep as anDroid</a>, ukázka aplikace.
Budík - umí měřit spánkové cykly. Umí nahrávat spánkovou aktivitu i zvuky, chrápání apod. Statistiky o spaní a návyky. Captcha pro budík, aby jste to snad nezamáčkli. Celé snímání je přes akcelerometr. Aplikace se dá snadno rozšiřovat. 330k aktivních uživatelů a 60k prodaných kusů.</p>

<p>9:43 AdMob - 910 miliard reklam už bylo zobrazeno.</p>

<p>9:45 Chrome a HTML5, Chrome Webstore</p>

<p>9:51 Ilmari Heikkinen - WebGL demo, <a href="http://mrdoob.github.com/three.js/">tree.js</a>, flux slider <a href="http://joelambert.co.uk/flux/transgallery.html">transgallery</a>, asteroids. Pěkné demo na Developers tools v Chrome, zvláště pretty print funkce pro javascript je hodně pěkná.</p>

<p>10:00 WebM Video, Web Audio Api, HTML5 s WebIntents, Native Client (C, CPP v sandboxu), JS a DOM. HTML5 aplikace lehce najdete přes Chrome Web Store a zítra HTML5 Hackathon zítra a jedou na Google IO.</p>

<p>10:05 Video, YouTube 3D - trailer na novou Dobu ledovou ve 3D</p>

<p>10:10 Mano Marks a Jarda Bengl - Google Maps
První Google Maps Mashup - <a href="http://housingmaps.com">http://housingmaps.com</a>. Google Fusion Tables - <a href="http://mano-demos.googlecode.com/svn/trunk/demos/europepopsliders.html">demo s populací evropy</a>. WebGL v mapách, klikněte vlevo dole vyzkoušet něco nového a mapy se přepnou do WebGL. Úžasné celé vektorové mapy místo obrázků a 3D budovy v normálních mapách provázání s satelitní mapou (ukázky New York, Rome, Venice).</p>

<p><img class="center" src="http://blog.prskavec.net//assets/googlemaps_webgl_1.png" title="'Venice'" ></p>

<center>Ukázka Venice, kde je vidět vektory a 3D domy.</center>


<p><img class="center" src="http://blog.prskavec.net//assets/googlemaps_webgl_2.png" title="'Rome'" ></p>

<center>Při zoomu jsou některé budovy vidět v náhledu 45 stupňů.</center>


<p><img class="center" src="http://blog.prskavec.net//assets/googlemaps_webgl_3.png" title="'Rome'" ></p>

<center>A dá se s nimi i otáčet.</center>


<p>10:24 Cloud, webová verze Angry Birds používá (GWT, HTML5, Google Plus, App Engine). Mobilní hry často App Engine používání na backendu (např. TapZoo). App Engine pro Google Doodles (<a href="http://www.google.com/logos/2011/lespaul.html">ukázka</a>, záznamy za 2 dny nahráli uživatelé několik let záznamů.</p>

<p><a href="http://code.google.com/apis/storage/">Google Cloud Storage</a>, <a href="http://code.google.com/apis/predict/">Google Prediction API</a> jdou do provozu z Labs.</p>

<p><a href="http://code.google.com/apis/sql/">Google Cloud SQL</a> uvádějí jako novinku. Iein Valdez uvedl demo. Použije se JDBC driver pro Google Cloud SQL (GCSQL). Ukázka na App Engine byla v Javě a PHP.</p>

<p>10:40 Google Plus s Circles, Hangouts, Mobile. Novinky přidávájí stále a během 90 dnů od spuštění přidali přes 100 novinek. Teď mají kolem 40M uživatelů a 3,4 mld. fotek. Plugins (+1 button), anotace pro vaše výsledky hledání. APIs (RESTful, JSON, OAuth2) a knihovny pro všechny běžné jazyky (<a href="https://code.google.com/apis/explorer">Google Apis Explorer</a>.</p>

<p>10:50 Jonathan Beri - Hangouts demo, přijde mi to jako Google Wave v nové verzi zaměřené více na to co lidé chtějí. Více o Google platform na <a href="https://developers.google.com/+/">https://developers.google.com/+/</a>.</p>

<p>Keynote končí.</p>

<h2>Ilmari Heikkinen - Tohle nejsou weby, které hledáte: Moderní webové aplikace v HTML5</h2>

<p>Definuje moderní webovou aplikaci jako desktop UI s cloud backendem (příklad DJBreakPoint aplikace).</p>

<p>MVC Frameworks (Sproutcore, BackboneJS, ExtJS 4). Css Frameworks (Less, Sass). Divné, že nezmínil AngularJS, který Google přímo podporuje a vyvíjí. Responsive layout pro notebooky, mobily a tablety.</p>

<ul>
<li><a href="http://formfactorjs.com">formfactorjs.com</a></li>
<li><a href="http://www.leviroutes.com">www.leviroutes.com</a> (pushState, řeší MVC JS Frameworky)</li>
</ul>


<p>Ukázka webkitdirectory a drag and drop pro práci se soubory v Chrome. Ukázka ukládání na filesystem. Application cache pro ukládání.</p>

<pre><code>&lt;html manifest='cache.appcache'&gt;
</code></pre>

<ul>
<li><a href="http://westcoastlogic.com/lawnchair/">LawnChair</a> - simple json storage</li>
<li>x-webkit-speech attribute například pro input.</li>
<li>desktop notifikace - webkitNotifications</li>
<li>performance tips - <a href="http://bit.ly/rizNVE">http://bit.ly/rizNVE</a></li>
</ul>


<h3>Old browsers</h3>

<ul>
<li>Chrome Frame</li>
<li>HTML5 Boiler Plate</li>
<li>Modernizr</li>
<li>jQuery</li>
</ul>


<h3>Chrome Web store</h3>

<ul>
<li>$5 poplatek za registraci</li>
<li>možnost monetizace HTML5 aplikací</li>
<li><a href="http://appmator.appspot.com/">AppMator</a> umí udělat manifest file</li>
</ul>


<p>Slidy <a href="http://bit.ly/nrjLs7">http://bit.ly/nrjLs7</a>.</p>

<p>Reportáž skončila.</p>

<h2>Shodnocení GDD 2011</h2>

<p>Později jsem se vrátil na GDD bohužel až na Ignite, ale ty rozhodně stály za to. Přišlo mi to jako skvělý závěr GDD2011 a co bych chtěl ocenit je i přes menší rozpočet spousta věcí zaujala. Ocenil bych více advanced přednášek, kde přednášející mi řekne něco co nevím, ale to je hodně individuální.</p>

<p>Jinak celkem dobrá organizace, trochu registrace vázla, když člověk přišel později. Celkově jsem potkal spoustu lidí, které vidím jen tady.</p>

<p>Za mě jediné přání do dalšího roku, líbil by se mi například <a href="https://github.com/vojtajina">Vojta Jína</a> nebo někdo s týmu <a href="http://angularjs.org/">AngularJS</a> a nějaký workshop s nimi ať na GDD nebo mimo.</p>

<h2>Update 24.10.2011</h2>

<p>K dispozici jsou <a href="http://www.youtube.com/watch?v=1Xn6CfJ713g&amp;feature=list_related&amp;playnext=1&amp;list=SP64D87C03BA3B2A88">všechny videa</a>. Úžasné!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Update blog na Octopress]]></title>
    <link href="http://blog.prskavec.net//2011/10/update-blog-na-octopress/" />
    <updated>2011-10-17T21:18:00+02:00</updated>
    <id>http://blog.prskavec.net//2011/10/update-blog-na-octopress</id>
    <content type="html"><![CDATA[<p>V <a href="http://blog.prskavec.net/2011/09/Migrace-z-Wordpressu-na-Jekyll/">předchozím příspěvku</a> jsem psal jak jsem migroval na Jekyll. Základní verze Jekyllu je hodně omezená a dá dost práce vylepšit ho podle představ. Mě šlo hlavně o čitelnost nějaké drobnosti, které jsem si na tom udělal, ale nebyl jsem zcela spokojený. Když jsem hledal dále ve svět Jekyllu a stránek pro pages na githubu narazil jsem na <a href="http://octopress.org/">Octopress</a>, který je dokonalý blogovací framework. <a href="http://brandonmathis.com/">Brandon Mathis</a> vytvořil krasný a funkční template, který má tyto vlastnosti:</p>

<ul>
<li>má HTML5 template</li>
<li>mobile friendly</li>
<li>podpora pro Twitter, Google Plus One, Disqus Comments, Pinboard, Delicious, and Google Analytics</li>
<li>jednoduchý deployment (rake deploy)</li>
<li>zvýrazňování zdrojové kódu (Solarized)</li>
<li>jednoduchá změna vzhledu pomocí Compass a Sass</li>
</ul>


<p>a další <a href="http://octopress.org/docs/plugins/">pluginy</a>, které jsou přesně co vývojář potřebuje. Pro mě jsou nejdůležitější</p>

<ul>
<li>Gist</li>
<li>jsFiddle</li>
<li>Include Code</li>
</ul>


<p>Doufám, že pokud se vám líbí Jekyll tak Octopress je ještě trochu lepší a na stejném základě.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Subversion 1.7]]></title>
    <link href="http://blog.prskavec.net//2011/10/Subversion-1.7/" />
    <updated>2011-10-12T00:00:00+02:00</updated>
    <id>http://blog.prskavec.net//2011/10/Subversion-1.7</id>
    <content type="html"><![CDATA[<h2>Dlouhé čekání na nový Subversion</h2>

<p>Myslím, že vetšina lidí si shlédnutí roadmapy Subversion a čekaní 2 roky na změny, které potřebují migrovala na jiný verzovací systém. Ale celosvětově je Subversion stále velice používaný verzovací systém.</p>

<h2>Novinky ve verzi 1.7</h2>

<p>Byla opraveny <a href="http://svn.apache.org/repos/asf/subversion/tags/1.7.0/CHANGES">spousty chyb</a> což jistě všichni uživatelé ocení. A přidáno několik novinek, ty nejvýznamější zmínim dále.</p>

<h3>WC-NG</h3>

<p>Za dlouho očekávanou novou verzí pracovní kopie (WC, working copy) je centralizace adresářů <code>.svn</code> do jednoho podobně jako to mají jiné verzovací systémy. Používá se nějaká forma SQLite, ale autoři upozorňují, že není bezpečné přistupovat k souboru s metadaty běžnými nástroji pro SQLite.</p>

<h3>HTTPv2</h3>

<p>Nový jednoduší HTTP protokol má samozřejmě hlavně zvýšit výkon SVN, kdy operace se serverem jsou největší zátěží uživatelů. Zatím, ale nemám k dispozici žádné porovnání rychlosti, kde by to bylo reálně vidět.</p>

<h3>svnrdump</h3>

<p>Příkaz <code>svnrdump</code> umožňuje to samé jako <code>svnadmin dump</code> na serveru i vzdáleně. Pokud jste ve staré verzi chtěli zálohovat pomocí svnadmin, museli jste mít přístup přímo k file systému, kde byl svn server. To teď odpadá.</p>

<h3>svn patch</h3>

<p><code>svn patch</code> složí jako systémový příkaz patch k aplikací diffů (patchů).</p>

<h3>Distribuce</h3>

<p>Postupně se objevují binární balíčky s Subversion 1.7</p>

<ul>
<li>Windows: <a href="http://www.visualsvn.com/server/download/">VisualSVN server</a></li>
</ul>


<h2>Závěr</h2>

<p>Nic převratného se nestalo, Subversion postupuje dále správným směrem a doufám, že další plánované změny budou probíhat trochu rychleji. Pokud Subversion nepoužíváte a chcete můžete se dozvědět více <a href="http://www.gopas.cz/Kurzy/Katalog-kurzu/Programovani/Design-architektura-metody-vyvoje/Verzovaci-system-Subversion-GOC1014.aspx">na mém školení, nejbližší je 20-21.10.2011</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Migrace z Wordpressu na Jekyll]]></title>
    <link href="http://blog.prskavec.net//2011/09/Migrace-z-Wordpressu-na-Jekyll/" />
    <updated>2011-09-30T00:00:00+02:00</updated>
    <id>http://blog.prskavec.net//2011/09/Migrace-z-Wordpressu-na-Jekyll</id>
    <content type="html"><![CDATA[<h2>Co jsem řešil</h2>

<p>V poslední době jsem neměl moc času na psaní a když jsem chtěl psát, chtěl jsem se tomu věnovat, mít na to jednoduchý prostředek jako je Textmate (ByWord, iA Writer, WriteRoom, OmmWriter) a přitom se nemuset handrkovat s HTML a s tím jak mi občas nevhodné styly ničí text nebo kusy kódu.</p>

<p>Wordpress u mě na hostingu ještě narazil na limit starého MySQL a mě se také nechtělo migrovat na nový databázový server, potom mi také chybělo verzování v Gitu na který jsem zvykl.</p>

<p>Protože jsem před časem viděl, že <a href="http://pages.github.com">Github pages</a> se dají dobře použít pro vlastní blog, rozhodl jsem se na to přejít se svými blogy <a href="http://blog.prskavec.eu">TopTopic?</a> a <a href="http://blog.prskavec.net">Prskavčí blog</a>.</p>

<h2>Jak jsem postupoval</h2>

<ol>
<li>Migrace starého obsahu z Wordpressu</li>
<li>CNAME a DNS</li>
<li>Nastavení stylů a práce s <a href="https://github.com/mojombo/jekyll/wiki/">Jekyll</a>

<ul>
<li>komentáře</li>
<li>twitter</li>
<li>atom feed</li>
</ul>
</li>
<li>Publikace na github.com</li>
</ol>


<h2>Jekyll - statický generátor stránek v Ruby</h2>

<p>Podporuje publikování v textile a markdown, případně html.</p>

<p>Instalace pomocí rubygems</p>

<div>
  <pre>
    <code class='sh'>sudo gem install jekyll</code>
  </pre>
</div>


<p>Pro ladění na lokálním počítači jde pustit lokální instanci, která běží <a href="http://localhost:4000">http://localhost:4000</a>.</p>

<div>
  <pre>
    <code class='sh'>jekyll --server --auto</code>
  </pre>
</div>


<p>Jekyll funguje tak, že na základě předpisu generuje statické stránky do adresáře <code>_site</code>. Parametr <code>auto</code> umí po editaci automaticky přegenerovat změněný soubor.</p>

<h2>Migrace z Wordpressu</h2>

<ol>
<li>Založte si adresář a začněte verzovat gitem.</li>
</ol>


<div>
  <pre>
    <code class='sh'>mkdir blog.prskavec.net
cd blog.prskavec.net
git init</code>
  </pre>
</div>


<ol>
<li><p>Je potřeba udělat export z Wordpressu, pomocí <code>export.php</code>.</p></li>
<li><p>Například u mě to bylo <code>http://blog.prskavec.net/wp-admin/export.php</code>.</p></li>
<li>Na výsledné xml je potřeba použít <a href="https://github.com/mojombo/jekyll/tree/master/lib/jekyll/migrators">importní script</a>.</li>
<li>K dispozici jsou importní scripty pro Wordpress, CSV, Drupal, Posterous, Tumblr, Typo, Textpattern, Wordpress.com a další</li>
<li><p>Já jsem si zkopíroval do adresáře <code>_import</code> zkopíroval scripty pro wordpress. Potom jsem provedl import.</p>

<p> ruby -r &#8216;./_import/wordpressdotcom.rb&#8217; -e &#8216;Jekyll::WordpressDotCom.process(&#8220;prskavblog.wordpress.2011-09-28.xml&#8221;)&#8217;</p></li>
<li><p>Všechny posty se uloží automaticky do <code>_post</code>.</p></li>
</ol>


<h2>CNAME a DNS</h2>

<ol>
<li>Do repository přidáte soubor CNAME který musí obsahovat doménu na které chcete Github pages provozovat, samozřejmě pokud vám nestačí stávající co dostanete od Githubu.</li>
<li>DNS - musíte si zřídít CNAME záznam, který bude ukazovat na váš záznam na githubu. U mě <code>abtris.github.com</code> pro doménu 3 řádu. Pokud by jste chtěli doménu 2 řádu musíte zřídit A záznam na 207.97.227.245.</li>
</ol>


<h2>Nastavení stylů a práce s Jekyll</h2>

<p>Základní struktura</p>

<pre><code>|-- _config.yml
|-- _layouts
|   |-- default.html
|   `-- post.html
|-- _posts
|   |-- 2007-10-29-why-every-programmer-should-play-nethack.textile
|   `-- 2009-04-26-barcamp-boston-4-roundup.textile
|-- _site
`-- index.html
</code></pre>

<p><code>_config.yml</code></p>

<pre><code>sitename: Prskavčí blog        
tagline: Jen další blog o všem možné, teď od Prskavců.
url: http://blog.prskavec.net   
ga: UA-XXXXX-XX                 
pygments:    true
markdown:    maruku
permalink:   pretty
exclude: LICENSE, README.markdown, Rakefile
disqus:
   id: prskavecblog
feedburner:
   id: prskavec
</code></pre>

<p>Nejdůležitější odkazy:</p>

<ul>
<li><a href="https://github.com/mojombo/jekyll/wiki/Usage">Použití</a></li>
<li><a href="https://github.com/mojombo/jekyll/wiki/Configuration">Konfigurace</a></li>
<li><a href="https://github.com/mojombo/jekyll/wiki/Configuration">Ukázkové stránky</a></li>
<li><a href="https://github.com/mojombo/jekyll/wiki/Template-Data">Důležité proměnné</a></li>
<li><a href="https://github.com/shopify/liquid/wiki/liquid-for-designers">Značkovací jazyk Liquid, který se používá v Jekyll šablonách</a></li>
<li><a href="https://github.com/mojombo/jekyll/wiki/Plugins">Pluginy</a></li>
<li><a href="http://pygments.org/docs/lexers/">Lexers for Pygments</a> - syntax hightlighting, příslušné <a href="https://github.com/mojombo/tpw/blob/master/css/syntax.css">syntax.css</a> třeba tady.
Samozřejmě pro svůj blog potřebujete nějak přispůsobit vzhled, pro Jekyll to není tak snadné jako Wordpress, který má spoustu pluginů a vzhledů. Ale není problém, některý z Wordpressu převést.</li>
</ul>


<p>Pluginy některé existují, ale musíte si vystačit s tím co jde vygenrovat, případně z Javascriptem, ale to není málo.</p>

<p>Pomocí javascriptu jsem přidat <a href="http://tweet.seaofclouds.com/">twitter</a> a komentáře přes <a href="http://disqus.com">Disqus</a>.</p>

<p>Pro ATOM je k dispozici šablona, obdobně si můžete vygenerovat RSS, archív apod.</p>

<h2>Publikace na Github</h2>

<ol>
<li>Založte si repositář na Githubu.</li>
<li>V adminu zapnout github pages.</li>
<li>Podle návodu přidejte do repositáře soubory a pushnete obsah na server.</li>
</ol>


<h2>Shrnutí</h2>

<p>Jekyll není pro každého, ale pro mě jako pro programátora je to vyhovující systém. Článek jako tento napíšu ve stejném editoru jako programuju ať je to <a href="http://macromates.com/">Textmate</a> nebo <a href="http://www.jetbrains.com/phpstorm/">PHPStorm</a>. A stránky jsou jen další repository na <a href="http://github.com">githubu</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Deployment prakticky - WebExpo 2011]]></title>
    <link href="http://blog.prskavec.net//2011/09/deployment-prakticky-webexpo-2011/" />
    <updated>2011-09-25T00:00:00+02:00</updated>
    <id>http://blog.prskavec.net//2011/09/deployment-prakticky-webexpo-2011</id>
    <content type="html"><![CDATA[<p>Letos jsem přednášel na Webexpu na téma deployment. Ve 30 minutách se nedá říci dost, aby jste se dozvěděli všechno tak zkusím v tomto článku shrnout o čem jsem mluvil a přidat nějaké zdroje, které pomůžou v dalších úsilí při automatizaci deploymentu.</p>

<h2 id="deployment">Deployment</h2>


<ul>
    <li>Nasazení dané aplikace na dané prostředí v daném čase s možností vrácení původní verze aplikace pokud možno s minimálními prostředky a náklady.</li>
</ul>


<h2 id="configuration_management">Configuration Management</h2>


<ul>
    <li>Služba, která se stará, aby námi zadaná konfigurace byla konzistentní napříč prostředím a na všech strojích a je to jeden nezbytných kroků pro CI.</li>
</ul>


<h2 id="continuous_integration">Continuous Integration</h2>


<p>CI pomáhá dramaticky snížit počet chyb při vývoji i v produkci pokud se to dělá dobře a důsledně.</p>

<p>Pro dobré fungovaní Continuous Integration potřebujete automatizovat deployment na prostředí. Na prostředích se často střídají aktuální feature větve vývojářů nebo se tam provádí update z větve pro release či sprint. K tomu se vše provádí několikrát denně. Abychom tohle mohli dělat potřebuje deployment mít plně automatický.</p>

<pre><code>"Automated deployment, tied into good CI discipline, is essential to making this work." - Martin Fowler
</code></pre>


<h2 id="tlatko_push">Tlačítko push</h2>


<p>Deployment musí být tak jednoduchý, aby ho zvládnul kdokoliv, kdo ho potřebuje a má potřebné oprávnění. Zdá se celkem jednoduché, ale není tomu tak. Pokud je potřeba například znalost linuxu (vytváření symlinku, ssh klient apod.), může to být pro část týmu třeba dost velká překážka, aby si něco nasadili a raději řeknou developerovi. On to má přece za minutku nasazené. Ale v tom je problém, pokud developer není po ruce, nebo nemá čas, tak část práce stojí. Obzvláště při agilním vývoji a krátkém sprintu to může být dost znát.</p>

<p>Pokud ještě se deployment dělá ručně, občas se na něco zapomene a jakákoliv ruční práce je zdrojem chyb. Celkově dojde k úspoře nákladů, protože čas ztrávený deploymentem firmě nikdo nezaplatí.</p>

<p>Za tlačítkem push si můžete představit jakýkoliv spouštěč, který vám vyhovuje (git push do příslušné větve, tlačítko na webu apod.).</p>

<p>Pokud nemáte zkušenost s gitem, tak rozvedu ten git push. Ostatní mohou odstavec přeskočit.</p>

<p>Git jako distribuovaný systém funguje jen lokálně a může mít svoje vzdálené kopie repository podobně jako v architektuře klient server (Subversion). Ale nemusí mít jen jedno místo kam se zdrojový kód odesílá pomocí git push. Toho se dá využít a používá se to tak, že kromě serveru kam ukládáte zdrojový kód (u mě například Github.com), který je označený jako origin (git push origin master - odešle kód tam), mohu například přidat místo kde se pushem přímo nasadí (git push heroku master - kód se odešle na cloud Heroku a dojde k jeho nasazení). Obdobně kromě místa, lze použít určité větve a mít na serveru hook script, který detekuje změny a provede nasazení.</p>

<ul>
    <li><a href="http://stackoverflow.com/questions/279169/deploy-a-project-using-git">http://stackoverflow.com/questions/279169/deploy-a-project-using-git</a></li>
    <li><a href="http://ryanflorence.com/deploying-websites-with-a-tiny-git-hook">http://ryanflorence.com/deploying-websites-with-a-tiny-git-hook </a></li>
</ul>


<h2 id="jak_to_nechat_na_jinch">Jak to nechat na jiných</h2>


<p>Pokud můžete a děláte projekt, kde se můžete dovolit využít hostingu, cloudu, který deployment vyřeší za vás, udělejte to. Ušetří vám to čas i prostředky. Samozřejmě ne vždy to jde, ale pro ty případy tu bude další kapitola.</p>

<h3 id="herokucom"><a href="http://heroku.com">Heroku.com</a></h3>


<ul>
    <li>Ruby, Node.js, Closure, Java (CLI client, rake pro příkazy jako jsou migrace db, hodně dodatečných služeb - <a href="http://addons.heroku.com/">http://addons.heroku.com/</a>)</li>
    <li>částečná podpora pro PHP a Python přes Facebook - <a href="https://developers.facebook.com/blog/post/558/">https://developers.facebook.com/blog/post/558/</a>.</li>
</ul>


<p>Další služby, recenze některých jsem dělal dříve.
- <a href="http://www.pagodabox.com">http://www.pagodabox.com</a>
- <a href="http://phpfog.com">http://phpfog.com</a>
- <a href="http://orchestra.io/">http://orchestra.io/</a>
- <a href="http://www.engineyard.com">http://www.engineyard.com</a>
- <a href="http://cloudcontrol.com/">http://cloudcontrol.com/</a>
- <a href="http://relbit.com">http://relbit.com</a>
- <a href="http://nodester.com/">http://nodester.com/</a></p>

<p>Samozřejmě jsem nemohl vyzkoušet podrobně každou cloudovou službu, na to nemám rozpočet a ne každá má k dispozici zdarma potřebný program pro vývojáře. Důležité aspoň pro mě je podpora práce z CLI kvůli možnosti automatizace, případně nějaké API, které to umožňuje. A také podpora vlastního nastavení a úkolů, aby jste mohli například automaticky spustit test nebo migraci databáze. Svoje zkušenosti nebo rady a doporučení uveďte do komentářů, budu rád.</p>

<h2 id="jak_si_to_vyrobit_sm">Jak si to vyrobit sám</h2>


<h3 id="rozdlen_nstroj_pro_deployment">Rozdělení nástrojů pro deployment</h3>


<ul>
    <li>balíčkovací systémy (<a href="http://en.wikipedia.org/wiki/Listofsoftwarepackagemanagement_systems">http://en.wikipedia.org/wiki/List<em>of</em>software<em>package</em>management_systems</a>)
<ul>
    <li>podle operačního systému (RPM, DEB)</li>
    <li>podle jazyka (phar, pear, gem, npm, cpan)</li>
</ul>
</li>
    <li>nástroje
<ul>
    <li>capistrano - <a href="http://capify.org/">http://capify.org/</a></li>
    <li>fabric - <a href="http://fabfile.org">http://fabfile.org</a></li>
    <li>cfengine - <a href="http://cfengine.com/">http://cfengine.com/</a></li>
    <li>puppet - <a href="http://puppetlabs.com/">http://puppetlabs.com/</a></li>
    <li>chef - <a href="http://www.opscode.com/">http://www.opscode.com/</a></li>
    <li>ant - <a href="http://ant.apache.org/">http://ant.apache.org/</a>, maven - <a href="http://maven.apache.org/">http://maven.apache.org/</a>, buildr - <a href="http://buildr.apache.org/">http://buildr.apache.org/</a></li>
    <li>make, rake, phake, phing apod.</li>
</ul>
</li>
</ul>


<h3 id="capistrano">Capistrano</h3>


<p>Instalace
- pro instalaci potřebujete ruby (windows - <a href="http://rubyinstaller.org/">http://rubyinstaller.org/</a>, mac - součást OS)
- pokud budete deployment dělat pro ruby aplikaci nepotřebujete samozřejmě railsless-deploy</p>

<pre><code>gem install capistrano capistrano-ext railsless-deploy
</code></pre>


<p>Zdrojový kód si stáhněte z <a href="https://github.com/abtris/webexpo2011-wordpress.git">githubu</a>.</p>

<pre><code>git clone https://github.com/abtris/webexpo2011-wordpress.git
</code></pre>


<p>Zajímají nás tyto soubory:</p>

<pre><code>Capfile
templates/apache.conf.erb
config/deploy/development.rb
config/deploy/production.rb
config/deploy/apache.rb
config/deploy/deploy.rb
</code></pre>


<p>které nám umožňují dělat deployment:
cap deploy
cap development deploy
cap production deploy</p>

<p>a configuration management:</p>

<pre><code>cap apache:setup
cap apache:start
cap apache:stop
cap apache:restart
</code></pre>


<h3 id="praktick_ukzka_capistrana_na_videu">Praktická ukázka Capistrana na videu</h3>


<ul>
    <li>používám virtuální server pro deployment, který je vytvořen pomocí Vagrant (<a href="http://www.vagrantup.com">www.vagrantup.com</a>) a Chef</li>
    <li>ukázka jak se vytváří Jenkins server pro testovaní - <a href="https://github.com/abtris/vagrant-hudson">https://github.com/abtris/vagrant-hudson</a></li>
</ul>


<iframe width="420" height="315" src="http://www.youtube.com/embed/MisWQe4JhEQ" frameborder="0" allowfullscreen></iframe>


<h2 id="jenkins_jak_se_to_dl_v_jobscz">Jenkins - jak se to dělá v Jobs.cz</h2>


<ul>
    <li>v LMC (jobs.cz, prace.cz) je vývoj v Javě a PHP. Pro oboje používáme od roku 2008 na build Hudson dnes Jenkins. Pro Javu se přechází na build postavená na Mavenu a v PHP používáme build napsaný v Antu, který vytváří RPM balíčky pro nasazení CFEngine nebo pomocí skriptu přímo z Jenkins.</li>
    <li>jak vyrobit RPM pro PHP - ukázka s kódem k dispozici <a href="https://github.com/abtris/barcamp2010praha">https://github.com/abtris/barcamp2010praha</a></li>
</ul>


<p>etc/demoapp.spec</p>

<pre><code>Summary: Demo App
Name: @@PACKAGE_NAME@@
Version: @@VERSION@@
Release: @@BUILD@@
License: Copyright by Ladislav Prskavec
Group: System Environment/Internet
BuildRoot: @@BUILDROOT@@

#topdir
%define _topdir @@TOPDIR@@
%define _target_os Linux

%description
Barcamp 2010 demo app

%install
mkdir -p $RPM_BUILD_ROOT/srv/www/demoApp/@@CURRENT@@
cp -r ${FILENAME}-${VERSION}/* $RPM_BUILD_ROOT/srv/www/demoApp/@@CURRENT@@/

%clean
[ "${RPM_BUILD_ROOT}" != "/" ] &amp;&amp; rm -rf ${RPM_BUILD_ROOT}

%files
/srv/www/demoApp/@@CURRENT@@

%defattr(755,root,root)
%dir /srv/
%dir /srv/www
%dir /srv/www/demoApp/
%dir /srv/www/demoApp/@@CURRENT@@/

%post
echo "run: ln -nfs /srv/www/demoApp/@@CURRENT@@/ /srv/www/demoApp/current"
</code></pre>


<p>a k tomu příslušný build script</p>

<pre><code>&lt;project name="project_name" default="clean" basedir="."&gt;
&lt;!-- task definition for cycle --&gt;
&lt;taskdef resource="net/sf/antcontrib/antlib.xml"/&gt;
    &lt;description&gt;
        barcamp demo app
    &lt;/description&gt;

  &lt;!-- options from properties file --&gt;
  &lt;!-- ${ws} is in Hudson $WORKSPACE --&gt;
  &lt;echo message="reading properties from: ${ws}/etc/build.properties" /&gt;
  &lt;echo message="module name ${modulename}" /&gt;
  &lt;property file="${ws}/etc/build.properties"/&gt;
  &lt;!-- options from .spec file --&gt;
  &lt;property name="spec_file" value="/etc/${modulename}.spec" /&gt;
  &lt;!--  make unique rpm_build_root, solve problems with branches --&gt;
  &lt;exec executable="mktemp" outputproperty="rpm_build_root"&gt;
    &lt;arg value="-d" /&gt;
    &lt;arg value="-t" /&gt;
    &lt;arg value="${modulename}.XXXXXXXXXX" /&gt;
  &lt;/exec&gt;
  &lt;echo message="RPM Build root set to: ${rpm_build_root}" /&gt;
  &lt;!-- set global properties for this build --&gt;
  &lt;property name="build" location="${rpm_build_root}/BUILD"/&gt;
  &lt;property name="rpms" location="${rpm_build_root}/RPMS"/&gt;

 &lt;target name="init"&gt;
    &lt;!-- Create the time stamp --&gt;
    &lt;tstamp/&gt;
    &lt;!-- Create the build directory structure used by compile --&gt;
    &lt;mkdir dir="${build}"/&gt;
    &lt;mkdir dir="${rpms}/i386"/&gt;
  &lt;/target&gt;

 &lt;target name="gitrevision" unless="REV" depends="init"&gt;
   &lt;exec executable="git" output="${rpm_build_root}/gitinfo"&gt;
     &lt;arg value="rev-list"/&gt;
     &lt;arg value="--all"/&gt;
   &lt;/exec&gt;
   &lt;exec executable="wc" output="${rpm_build_root}/wcinfo"&gt;
     &lt;arg value="-l" /&gt;
     &lt;arg value="${rpm_build_root}/gitinfo" /&gt;
   &lt;/exec&gt;
   &lt;exec executable="awk" outputproperty="REV"&gt;
     &lt;arg value="{ print $1 }"/&gt;
     &lt;arg value="${rpm_build_root}/wcinfo"/&gt;
   &lt;/exec&gt;
   &lt;echo message="REV: ${REV}" /&gt;
 &lt;/target&gt;

 &lt;target name="gitexport" depends="gitrevision"&gt;
  &lt;mkdir dir="${build}/${modulename}-${REV}" /&gt;
  &lt;copy todir="${build}/${modulename}-${REV}"&gt;
    &lt;fileset dir="../"&gt;
      &lt;exclude name="../.git/*"/&gt;
    &lt;/fileset&gt;
  &lt;/copy&gt;
   &lt;echo message="Coping files ..." /&gt;
 &lt;/target&gt;

 &lt;!-- take spec files  --&gt;
 &lt;target name="spec" depends="gitexport"&gt;
        &lt;!-- get spec files --&gt;
        &lt;path id="spec.files"&gt;
            &lt;fileset  dir="${build}/${modulename}-${REV}/etc"&gt;
                &lt;include name="*.spec"/&gt;
            &lt;/fileset&gt;
        &lt;/path&gt;
        &lt;!-- convert slashes to unix (necessary for Win) --&gt;
        &lt;pathconvert pathsep="," targetos="unix" property="files" refid="spec.files"/&gt;

        &lt;echo message="Call RPM" /&gt;
        &lt;!-- Call RPM for all spec files (task for need antcontrib --&gt;
        &lt;for list="${files}" param="item"&gt;
        &lt;sequential&gt;
            &lt;antcall target="replace"&gt;
                &lt;param name="spec_file" value="@{item}"/&gt;
            &lt;/antcall&gt;
            &lt;antcall target="rpm"&gt;
                &lt;param name="spec_file" value="@{item}"/&gt;
            &lt;/antcall&gt;
        &lt;/sequential&gt;
        &lt;/for&gt;

 &lt;/target&gt;

  &lt;!-- replace tokens in spec files --&gt;
  &lt;target name="replace"&gt;
    &lt;replace file="${spec_file}" token="@@CURRENT@@" value="${major_version}-${REV}"/&gt;
    &lt;replace file="${spec_file}" token="@@TOPDIR@@" value="${rpm_build_root}"/&gt;
    &lt;replace file="${spec_file}" token="${VERSION}" value="${REV}"/&gt;
    &lt;replace file="${spec_file}" token="${FILENAME}" value="${modulename}"/&gt;
    &lt;basename property="spec.filename" file="${spec_file}" suffix=".spec" /&gt;
    &lt;echo message="${spec.filename}" /&gt;
    &lt;replace file="${spec_file}" token="@@PACKAGE_NAME@@" value="${spec.filename}"/&gt;
    &lt;replace file="${spec_file}" token="@@VERSION@@" value="${major_version}"/&gt;
    &lt;replace file="${spec_file}" token="@@BUILD@@" value="${REV}"/&gt;
    &lt;replace file="${spec_file}" token="@@BUILDROOT@@" value="${rpm_build_root}-${spec.filename}/" /&gt;
    &lt;replace file="${spec_file}" token="@" value=""/&gt;
  &lt;/target&gt;

 &lt;!-- rpmbuild  --&gt;
 &lt;target name="rpm"&gt;
   &lt;echo message="SPEC: ${spec_file}" /&gt;
   &lt;exec executable="rpmbuild"&gt;
      &lt;arg value="--target=i386"/&gt;
      &lt;arg value="-bb"/&gt;
      &lt;arg value="${spec_file}"/&gt;
   &lt;/exec&gt;

 &lt;/target&gt;

  &lt;!-- copy RPM files to TOP_DIR and delete tmp dirs --&gt;
  &lt;target name="clean" depends="spec"&gt;
    &lt;copy todir="${target_path}"&gt;
        &lt;fileset  dir="${rpms}/i386/"&gt;
        &lt;include name="*.rpm"/&gt;
    &lt;/fileset&gt;
    &lt;/copy&gt;  &lt;/target&gt;

&lt;/project&gt;
</code></pre>


<h3 id="infrastructure_as_code">Infrastructure As code</h3>


<p>Pokud máte k dispozici více prostředí, nebo pokud používáte masivnější virtualizaci jistě víte, že to bez automaticace nejde.</p>

<p>K nejznámějším nástrojům patří CFEngine, Puppet a Chef.</p>

<pre><code>1993 - CFEngine
2002 - CFEngine 2
2005 - Puppet
2009 - CFEngine 3, Chef
</code></pre>


<p>O chefu jsem se zmiňoval již dříve, je vhodný právě například pro tvorbu virtualizací ve velkém. Pro příklad uvedu cluster <a href="http://blog.cyclecomputing.com/2011/09/new-cyclecloud-cluster-is-a-triple-threat-30000-cores-massive-spot-instances-grill-chef-monitoring-g.html">Nostromu</a>, který měl 30 000 jader.</p>

<p>Puppet
- http://www.puppetlabs.com
- napsaný v Ruby, odvozený od cfengine
- klient aktualizuje konfiguraci v pravidelných intervalech a reportuje zpět na server (Puppet Master)
- perfektní pro “sysadmins”
- deklarativní popis nastaveni</p>

<p>Chef
- http://www.opscode.com/chef
- v Ruby, odvozený od Puppetu
- Ruby DSL
- cloud provisioning
- imperativní popis, více flexibilní, více pro “vývojáře”
- pokud by vás to zajímalo doporučuji zajít na <a href="bit.ly/skolenichef">školení Radima Marka</a> (GoodData) - s kódem WEBEXPO2011 by měla být sleva 15%</p>

<h2 id="slidy">Slidy</h2>


<div style="width:425px" id="__ss_9388737"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/ladislavprskavec/deployment-prakticky" title="Deployment prakticky" target="_blank">Deployment prakticky</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/9388737" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe> <div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/ladislavprskavec" target="_blank">Ladislav Prskavec</a> </div> </div>


<h2 id="zvr_co_si_odnst">Závěr - co si odnést</h2>


<ul>
    <li>Existují kvalitní nástroje pro deployment, použijte je!</li>
    <li>Každý oprávněný uživatel si lehce zjistí informaci o verzi aplikace na příslušném prostředí a jednoduše si nasadí verzi aplikace, kterou potřebuje na prostředí, kde to potřebuje.</li>
    <li>Jedině automatizací se vyhnete chybám. Každý ruční postup jednou selže.</li>
    <li>Uspoříte velké náklady, protože čas ztraceny deploymentem nepřináší žádný zisk.</li>
</ul>




<blockquote><p><h4>Jenkins - jak na Continuous Integration v PHP</h4><br/>Pochopení a využití procesu Continuous Integration s využitím nástroje Jenkins vám pomůže zvýšit kvalitu softwaru, který vyvíjíte, a zároveň snížit čas na jeho dodávku. Continuous Integration vám umožňuje kontrolovat kvalitu softwaru průběžně po malých částech a minimalizovat tak riziko rozsáhlých chyb, jak tomu bylo v případě klasického vodopádového přístupu.</p><footer><strong>Ladislav Prskavec - Kurz Jenkins</strong> <cite><a href='http://webexpo.cz/academy/kurzy/jenkins-jak-na-continuous-integration-v-php'>WebExpo Academy</a></cite></footer></blockquote>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[WebExpo 2011 - Na co půjdu]]></title>
    <link href="http://blog.prskavec.net//2011/09/webexpo-2011-na-co-pujdu/" />
    <updated>2011-09-19T00:00:00+02:00</updated>
    <id>http://blog.prskavec.net//2011/09/webexpo-2011-na-co-pujdu</id>
    <content type="html"><![CDATA[<p>Jako vývojář jsem si vybral přednášky v Development Room a Development Hall.</p>

<p>V pátek začnu na přednášce co má Michal Táborský o Architektuře škálovatelných aplikací, jistě se dozvíme jak to dělají v Mall.cz. Michala znám a jeho vyprávění a postřehy mi přijdou velmi podobné tomu jako to řešíme v práci i my. Pokračovat budu na své přednášce, kde řeknu něco o tom proč automatizovat deployment, co na to použít. Jak to řešíme v LMC (Jobs.cz, Prace.cz). Po mě na podobné téma Honza Mittner bude pokračovat o konkrétním řešení deploymentu pro PHP u nich v agentuře.</p>

<p>V další sekci je na téma Javascript. JIŘÍ KNESL bude ukazovat Test Driven Development v CoffeeScriptu. Po něm bude pokračovat VOJTA JÍNA s MVC frameworkem  AngularJS. Protože používím BackboneJS, zajímá mě srovnání s AngularJS.</p>

<p>Protože ve svých projektech používám Google Maps Api, zajímají mě přednášky o konkurenci. Podívám se jak to dělají u Nokie (MICHAL AICHINGER, Nestačí vám vaše oblíbené mapové API? Zkuste Nokia mapy) a u Seznamu, kde nám ADAM CHVAJA řekne o On-line mapách u nás a ve světě.</p>

<p>Protože, pracuji s CouchDB a provoz MongoDB se spíše vyhýbám, tak se těším na zkušenosti z Centra v přednášce Lukáše LINHARTa o  MongoDB.</p>

<p>Nakonec to nejlepší DOUGLAS CROCKFORD, Serversideness, jednoznačná nejzajímavější přednáška letošního Webexpa, doufám, že nezklame.</p>

<p>V sobotu budeme pokračovat, nejprve se podívám na to co bude PAVEL CAMPR a JIŘÍ PRAUS povídat o Symfony 2, které mi přijde asi jako nejpropracovanější PHP framework dneška. RASMUS LERDORF a jeho PHP in 2011 je povinnost pro každého kdo programuje aspoň trochu v PHP. Michal Špaček ze Skypu a jaho Strategie kešování jistě nezklame.</p>

<p>Velice se těším na přednášku Scala - jazyk budoucnosti, ZDENĚK FARANA nám ukáže v čem je tento jazyk tak zajímavý a já dám možná JVM ještě někdy šanci.</p>

<p>KAREL MINAŘÍK a LUKÁŠ VLČEK jsou nejznámější vývojáři co mají u nás dělají s ElasticSearch. Karel je autorem ruby gemu Tire na práci s ES a Lukáš napsal jeden z nástrojů pro monitoring a přispívá k vývoji ES. Jejich ElasticSearch: Za hranice běžného fulltextového vyhledávání bude jistě jedna z nejzajímavějších přednášek Webexpa.</p>

<p>HONZA KRÁL je známý Python vývojář a ukáže nám jak se má psát kód tak, aby byl testovatelný a jeho Testování prakticky určitě bude zajímavé pro všechny vývojáře i testery. JAKUB VRÁNA s přednáškou Ajaxizace určitě zaujme.</p>

<p>Doufám, že se tam uvidíme a zkuste dát svoje tipy co vás zaujalo.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PHP a RabbitMQ]]></title>
    <link href="http://blog.prskavec.net//2011/04/php-a-rabbitmq/" />
    <updated>2011-04-10T00:00:00+02:00</updated>
    <id>http://blog.prskavec.net//2011/04/php-a-rabbitmq</id>
    <content type="html"><![CDATA[<p>V poslední době se objevilo hodně článků o <a href="http://www.rabbitmq.com/">RabbitMQ</a> a připravuje se <a href="http://manning.com/videla/">kniha</a> kde většina příkladů je v PHP.  Připravil jsem malou demonstraci jak se message queue dobře využit. RabbitMQ je napsaný v Erlangu podobně jako CouchDB a hodí ke zpracování dávkových úloh. V demonstraci využívám knihovnu <a href="http://code.google.com/p/wkhtmltopdf/">wkhtmltopdf</a> která umí zpracovat html stránku na PDF, používá k tomu webkit jádro.</p>

<h2>Design</h2>


<p>Malý design aplikace jsem zvolil takto:  <img class="aligncenter" title="rabbitmq_design" src="https://github.com/abtris/php-rabbitmq-wkhtmltox-demo/raw/master/docs/design.png" alt="" width="600" /></p>

<h2>Kód</h2>


<p>Základ aplikace jsou dva úlohy producer a consumer. Nejdříve je potřeba pustit consumer.</p>

<pre class="code">error_reporting(E_ALL);
/**
 * Application path
 */
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
/**
 * Application enviroment
 */
define('APPLICATION_ENV', 'development');

require_once APPLICATION_PATH . '/models/Rabbit.php';
/**
 * /Ensure library/ is on include_path
 */
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path()
)));

/** Zend_Application */
require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);
$application-&gt;getBootstrap()-&gt;bootstrap();

$config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV);

$r = new Application_Model_Rabbit($config-&gt;rabbitmq);
$r-&gt;consumer();</pre>


<p>Tento script musí běžet na serveru, kde se zpracovává vlastní požadavek. Model potom volá metodu, která se vykoná.</p>

<pre class="code">        $conn = new AMQPConnection($this-&gt;options['host'],
                                   $this-&gt;options['port'],
                                   $this-&gt;options['user'],
                                   $this-&gt;options['pass'],
                                   $this-&gt;options['vhost']
        );

        $channel = $conn-&gt;channel();
        /**
         * $exchange, $type,$passive=false,$durable=false,$auto_delete=true,
         */
        $channel-&gt;exchange_declare(self::EXCHANGE, 'direct', false, true, false);
        $channel-&gt;queue_declare(self::QUEUE);
        $channel-&gt;queue_bind(self::QUEUE, self::EXCHANGE);

        $consumer = function($msg) {
          $msg-&gt;delivery_info['channel']-&gt;basic_cancel($msg-&gt;delivery_info['delivery_tag']);
          if ($msg-&gt;body == 'quit') {
              $msg-&gt;delivery_info['channel']-&gt;basic_cancel($msg-&gt;delivery_info['consumer_tag']);
          } else {
              if (!empty($msg-&gt;body))  {
                  // make PDF
                  Application_Model_Wkhtmltopdf::proceed($msg-&gt;body, APPLICATION_PATH . '/../output/');
                  // notify user
                  system("growlnotify -n \"Rabbit demo\" -m \"PDF CREATED\"");
              }
          }
        };

        $channel-&gt;basic_consume(self::QUEUE,
                                self::CONSUMER_TAG,
                                false,
                                false,
                                false,
                                false,
                                $consumer);
        while (count($channel-&gt;callbacks)) {
            $channel-&gt;wait();
        }

        $channel-&gt;close();
        $conn-&gt;close();</pre>


<p>Vlastní aplikace je potom jednoduchá</p>

<pre class="code">    public function indexAction()
    {
        $r = new Application_Model_Rabbit($this-&gt;_config-&gt;rabbitmq);

        $this-&gt;view-&gt;form = $form = new Application_Form_AddUrl();
        // process form
        if ($this-&gt;getRequest()-&gt;isPost()) {
            $formData = $this-&gt;getRequest()-&gt;getParams();
            if ($form-&gt;isValid($formData)) {
                $r-&gt;setUrl($form-&gt;url-&gt;getValue());
                $r-&gt;run();
            } else {
                $form-&gt;populate($formData);
            }
        }

        $this-&gt;view-&gt;url = $r-&gt;getUrl();
    }</pre>


<p>a volá se producer, který invokuje RabbitMQ</p>

<pre class="code">        $conn = new AMQPConnection($this-&gt;options['host'],
                                   $this-&gt;options['port'],
                                   $this-&gt;options['user'],
                                   $this-&gt;options['pass'],
                                   $this-&gt;options['vhost']
        );
        $channel = $conn-&gt;channel();
        $channel-&gt;exchange_declare(self::EXCHANGE,
                                   'direct',
                                   false,
                                   true,
                                   false);
        $msg = new AMQPMessage($string, array('content-type' =&gt; 'text/plain'));
        $channel-&gt;basic_publish($msg, self::EXCHANGE);
        $channel-&gt;close();
        $conn-&gt;close();</pre>


<p>Demo u mne funguje velmi dobře, nevím jak na jiných platformách, zkoušel jsem to jen na Macu. Na linuxu by to mělo fungovat obdobně. Jen pro webovou aplikaci by bylo vhodné použít jiný systém notifikace pro webovou aplikaci. Nenašel jsem jak například předávat notifikace přes RabbitMQ, ale pokud někdo víte jak to elegatně udělat přidejte to do komentářů.</p>

<p>Veškerý zdrojový kód je <a href="https://github.com/abtris/php-rabbitmq-wkhtmltox-demo">dostupný na githubu</a>.</p>

<p>Zvolil jsem jednoduché jednosměrné řešení bez implementace RPC, kde by se dala pro notifikaci použít reply fronta. Ale myslím, že to celkem stačí pro vetšinu dávkových aplikací jako jsou logovaní, upload souborů i generovaní PDF. Nic nebrání nahradit moji notifikaci například posláním linku ke stažení výsledného PDF apod. Příklad by šel pomocí RPC vylepšit na notifikaci přímo v aplikaci. Pro implementaci RPC lze například použít <a href="https://github.com/tnc/Thumper">Thumper</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[phpfog - cloudové řešení pro PHP?]]></title>
    <link href="http://blog.prskavec.net//2011/03/phpfog-cloudove-reseni-pro-php/" />
    <updated>2011-03-14T00:00:00+01:00</updated>
    <id>http://blog.prskavec.net//2011/03/phpfog-cloudove-reseni-pro-php</id>
    <content type="html"><![CDATA[<p>Pokud se zajímáte o cloudové technologie, tak možná znáte <a href="http://heroku.com/">Heroku</a>. Heroku je pěkné řešení pro Ruby, které vám umožní vytvářet aplikace v Sinatře nebo v Rails a deployment provádět pomocí Gitu. Pro PHP mi něco takového dlouho chybělo, ale začíná se částečně situace vylepšovat, protože je na světe <a href="http://phpfog.com">PHP Fog</a>.</p>

<p><a href="http://blog.prskavec.net/wp-content/uploads/2011/03/phpfog-homepage-3.jpg"></a><a href="http://blog.prskavec.net/wp-content/uploads/2011/03/phpfog-homepage-4.jpg"><img class="aligncenter size-medium wp-image-6432" title="phpfog-homepage-4" src="http://blog.prskavec.net/wp-content/uploads/2011/03/phpfog-homepage-4-300x163.jpg" alt="" width="300" height="163" /></a></p>

<h2>Co vám přinese PHP Fog</h2>


<p>Mě se na cloudovém řešení libí, že je to pro vývojáře jednoduché a praktické. Nemusím řešit server, jeho provoz. Jen si nastavím konfiguraci apache, php.ini a vytvořenou aplikaci si přes git push pošlu na server k deploymentu a za pár okamžiků to běží.</p>

<p>Podobně to lehce vyřeším i na svém serveru pomocí SSH a Capistrano, ale stejně se musím starat o instalaci VPS. Jednodušší varianta je jen hosting s SSH přístupem například co mám na <a href="http://www.hostmonster.com">Hostmonster</a>. Tam je problém, ale se škálováním pokud by se stal projekt úspěšný.</p>

<p>Ukážu jak jsem během 5min rozběhl Zend Framework projekt s CouchDb hostovanou na couchone hostingu. Můžete použít MySQL, další db přímo hosting nepodporuje. Doufám, že to časem rozšíří hlavně o podporu PostgreSQL a některé NoSQL (CouchDb, MongoDb).</p>

<ul>
    <li>PHP Version 5.3.2</li>
    <li>Apache Version 2.2.14</li>
    <li>MySQL Version 5.1.41</li>
</ul>


<h2>Vytvoření nové aplikace</h2>


<p>Po přihlášení, zatím přístup je omezen, registrace přes nějaké <a href="https://phpfog.com/#sign-up">Sign Up kódy</a>, dostupný link najdete na homepage PHP Fog. Pokud chci vytvořit novou aplikaci, musím si vybrat profil, kde jsou setupy pro známé frameworky nebo přímo aplikace.</p>

<p><a href="http://blog.prskavec.net/wp-content/uploads/2011/03/phpfog-newapp-3.jpg"><img class="aligncenter size-medium wp-image-6422" title="phpfog-newapp-3" src="http://blog.prskavec.net/wp-content/uploads/2011/03/phpfog-newapp-3-300x171.jpg" alt="" width="300" height="171" /></a></p>

<p>Já jsem zvolil zend framework a pokračoval k dalšímu kroku, kde si vybere formu hostingu. Na prvních 6 měsíců můžete zvolit variantu zdarma. V dokumentaci se píše, že bude po těch 6 měsících nějak zpoplatněna. To si myslím, že není moc dobrý tah a autoři doufám od toho upustí.</p>

<p><a href="http://blog.prskavec.net/wp-content/uploads/2011/03/phpfog-price-3.jpg"><img class="aligncenter size-medium wp-image-6423" title="phpfog-price-3" src="http://blog.prskavec.net/wp-content/uploads/2011/03/phpfog-price-3-300x116.jpg" alt="" width="300" height="116" /></a></p>

<p>Po zvolení tarifu tak se dostanete do nastavení kde je potřeba poladit pár věcí a udělat si checkout Git repository pro váš projekt. Najde si v nastavení také nastavení Vhostu apache a php.ini.</p>

<p>Hlavní nastavení je nahrání SSH public key pro přístup ke Gitu, podobně jako na Githubu. Škoda, že se nedá přímo integrovat například pomocí nastavení remote větve na Github server. SSH a FTP přístup není k dispozici.</p>

<p><a href="http://blog.prskavec.net/wp-content/uploads/2011/03/phpfog-sourcecode-3.jpg"><img class="aligncenter size-medium wp-image-6424" title="phpfog-sourcecode-3" src="http://blog.prskavec.net/wp-content/uploads/2011/03/phpfog-sourcecode-3-300x99.jpg" alt="" width="300" height="99" /></a></p>

<p>Potom jsem udělal git checkout, nahrál do repository kód a pomocí git push spustil aplikaci, která běží na doméně podle jména které zadáte při vytváření aplikace. Provoz aplikace částečně můžete kontrolovat pomocí nahlížení do logů apache přes webové rozhraní.</p>

<p><a href="http://blog.prskavec.net/wp-content/uploads/2011/03/phpfog-logs-3.jpg"><img class="aligncenter size-medium wp-image-6421" title="phpfog-logs-3" src="http://blog.prskavec.net/wp-content/uploads/2011/03/phpfog-logs-3-300x157.jpg" alt="" width="300" height="157" /></a></p>

<h2>Závěr</h2>


<p>Projekt je na začátku a doufám, že bude mít štěstí a že se mu brzo objeví i další konkurenti, protože do Heroku to má daleko, ale jdou dobrou cestou. Trochu mi přijde cenová politika trochu dražší než bežná jiná řešení, ale asi to bude daň za provoz na Amazon cloudu (MySQL).</p>

<p>Pokud jste to někdo další vyzkoušeli nebojte se o to s námi podělit, případně nevíte někdo o dalších alternativách pro PHP?</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Podpora profilování cachegrind/KCachegrind v Xdebugu]]></title>
    <link href="http://blog.prskavec.net//2011/02/podpora-profilovani-cachegrindkcachegrind/" />
    <updated>2011-02-23T00:00:00+01:00</updated>
    <id>http://blog.prskavec.net//2011/02/podpora-profilovani-cachegrindkcachegrind</id>
    <content type="html"><![CDATA[<p>Dnes je část profilování v Xdebugu (<a title="Xdebug je open-source nástroj na ladění PHP. " href="http://xdebug.org">http://xdebug.org</a>) ukládána do souborů v KCacheGrind formátu. Tato funkce byla přidána do Xdebugu, ale není dle <a href="http://kcachegrind.sourceforge.net/html/CallgrindFormat.html">specifikace formátu</a>. Byla vytvořena revezním inženýrstvým a tato stávající implementace obsahuje chyby a nepřesnosti.</p>

<p>Od verze 0.6 je KCacheGrind více striktní ohledně interpretace formátu a to způsobuje chyby při jeho používání s výstupy Xdebugu  <a href="https://bugs.kde.org/show_bug.cgi?id=256425">https://bugs.kde.org/show_bug.cgi?id=256425</a>.</p>

<p><strong>Vybraná částka</strong> bude použita, aby <strong>Derick Rethans</strong> mohl správně vyřešit problém s integrací Xdebugu/KCacheGrindu. Správně vyřešit znamená, že předělá celou část zapisu profilovacích souborů. Rozhodně se tedy nejedná jen o jednoduchou opravu chyby jako je přidání jednoho řádku.</p>

<p><strong>Dnes 2.3.2011 byla částka úspěšně vybrána, všem co přispěli na dobrou věc děkuji.</strong></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PHPStorm 2.0 - nová verze multiplatformního vývojového prostředí]]></title>
    <link href="http://blog.prskavec.net//2011/02/phpstorm-2-0/" />
    <updated>2011-02-14T00:00:00+01:00</updated>
    <id>http://blog.prskavec.net//2011/02/phpstorm-2-0</id>
    <content type="html"><![CDATA[<p>Dnes 14.2.2011 vyšela nová verze IDE pro PHP od <a title="JetBrains :: World's Leading Vendor of Professional Development Tools" href="http://www.jetbrains.com/">JetBrains</a> <a title="PHP IDE :: JetBrains PhpStorm" href="http://www.jetbrains.com/phpstorm/">PHPStorm 2.0</a>.</p>

<h3>Hlavní výhody tohoto IDE</h3>


<ul>
    <li>základní vlastnosti IDE
<ul>
    <li>jednoduchá instalace</li>
    <li>rychlý start</li>
    <li>funguje na Windows, Linux a Mac OS X</li>
    <li>jednoduchá konfigurace projektů, můžete začít kde chcete</li>
</ul>
</li>
    <li>inteligentní php editor
<ul>
    <li>doplňování kódu</li>
<a href="http://blog.prskavec.net/wp-content/uploads/2011/02/php-code-completation-2.jpg"><img class="aligncenter size-full wp-image-6379" title="php-code-completation-2" src="http://blog.prskavec.net/wp-content/uploads/2011/02/php-code-completation-2.jpg" alt="" width="700" /></a>
    <li>refaktoring</li>
    <li>podpora pro Smarty a PhpDoc</li>
<a href="http://blog.prskavec.net/wp-content/uploads/2011/02/phpdoc-support-1-2.jpg"><img class="aligncenter size-full wp-image-6381" title="phpdoc-support-1-2" src="http://blog.prskavec.net/wp-content/uploads/2011/02/phpdoc-support-1-2.jpg" alt="" width="298" height="136" /></a>
<a href="http://blog.prskavec.net/wp-content/uploads/2011/02/php-doc-support-2-2.jpg"><img class="aligncenter size-medium wp-image-6380" title="php-doc-support-2-2" src="http://blog.prskavec.net/wp-content/uploads/2011/02/php-doc-support-2-2-300x178.jpg" alt="" width="300" height="178" /></a>
    <li>rychlá navigace (fuzzy search)</li>
    <li>editor pro mixování jazyků (html, js, xml, xsl)</li>
    <li>vlastní různé konfigurace vzhledů IDE kompatibilní s IDEA platform (IDEA, Rubymine)</li>
</ul>
</li>
    <li>pokročilý javascriptový editor
<ul>
    <li>procházení DOMu</li>
    <li>javascriptový debugger</li>
    <li>javascriptový refaktoring</li>
    <li>jako u php je navigace v kódu a vyhledávání užití</li>
</ul>
</li>
    <li>html a css editor
<ul>
    <li>podpora HTML5</li>
    <li><a title="zen-coding - Project Hosting on Google Code" href="http://code.google.com/p/zen-coding/">Zen</a> coding</li>
    <li>validace a rychlé opravy</li>
    <li>ukázky aplikovaných stylů</li>
</ul>
</li>
    <li>chytré prostředí
<ul>
    <li>podpora pro <a href="http://www.phpunit.de">phpunit</a></li>
    <li>podpora verzovacích systémů (<a href="http://subversion.apache.org">SVN</a>, CVS, <a href="http://www.git-scm.com">Git</a>, Mercurial a další)</li>
    <li>FTP a synchronizace vzdálených souborů</li>
    <li>Lokální historie souborů</li>
</ul>
</li>
    <li>visuální debugger
<ul>
    <li>podpora pro xdebug i zend debugger</li>
    <li><a href="http://blogs.jetbrains.com/webide/2011/02/zero-configuration-debugging-with-xdebug-and-phpstorm-2-0/">jednoduchá konfigurace</a></li>
    <li>breakpointy v PHP, JS, HTML</li>
</ul>
</li>
</ul>


<p><a href="http://blog.prskavec.net/2010/02/jetbrains-phpstorm/">Minulý rok jsem psal o verzi 1.0</a>, od té doby prostředí bylo velmi vylepšeno a stále se pracuje na vylepšení. Jetbrains chtějí konkurovat Zend Studiu a to není lehký soupeř.</p>

<p>Osobně mě nejvíce vyhovuje fuzzy vyhledávání v souborech, kde lehce najdu při práci se Zend Frameworkem příslušnou šablonu ke controlleru a velmi slušně funguje i potřebné vyhledání užití nebo nápověda.</p>

<p><a href="http://blog.prskavec.net/wp-content/uploads/2011/02/quick-documentation.jpg"><img class="aligncenter size-full wp-image-6387" title="quick-documentation" src="http://blog.prskavec.net/wp-content/uploads/2011/02/quick-documentation.jpg" alt="" width="764" /></a></p>

<p>V práci používám Zend Studio. Doma jsem dříve pracoval v Netbeans. Minulý rok jsem si při přechodu Mac OS X si koupil licenci PHPStorm 1.0, která obsahuje i 1 rok podpory včetně všech upgradů (tedy i verze 2.0) na které pracuji doteď. Zadal jsme několik chyb a podnětů a všemi se vývojáři zabývali a nějak je řešili.</p>

<p>Závěrem chci říct, že IDE je potřeba vyzkoušet a uvidíte jak jak vám sedne. Trial verze je zdarma k vyzkoušení a pokud znáte platformu IDEA tak využijete i spoustu pluginů, které jsou pro IntelliJ IDEA a Rubymine.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Vytváření vývojového Virtuálního prostředí pomocí VirtualBoxu a Vagrantu]]></title>
    <link href="http://blog.prskavec.net//2011/02/vytvareni-vyvojoveho-virtualniho-prostredi-s-pomoci-virtualboxu-a-vagrantu/" />
    <updated>2011-02-02T00:00:00+01:00</updated>
    <id>http://blog.prskavec.net//2011/02/vytvareni-vyvojoveho-virtualniho-prostredi-s-pomoci-virtualboxu-a-vagrantu</id>
    <content type="html"><![CDATA[<p><a href="http://www.virtualbox.org/">Oracle VirtualBox</a> je známé virtualizační prostředí pro platformy linux, mac a windows. Já VirtualBox používám na linux, mám na něm Ubuntu, které používám na školení Subversion nebo na vývoj webových aplikací jako server. Do nedávna jsem to používal na Macu nebo Linux pro běh Windows apod. O tomto používání nechci dnes mluvit.</p>

<p><a href="http://www.vagrantup.com">Vagrant</a> je nástroj napsaný v Ruby, který nám umožňuje modifikovat virtualní stroj podle našich představ pomocí nějakého předpisu, který nám udělá co chceme. Ukážeme si to na příkladu, že připravím linuxový server pro webový vývoj s Apache, PHP5, MySQL, CouchDB.</p>

<p>Začneme instalací Vagrantu</p>

<pre class="code">sudo gem install vagrant
vagrant box add base http://files.vagrantup.com/lucid32.box</pre>


<p>Vytvoříme si ukázkový projekt.</p>

<pre class="code">mkdir vagrant-lamp
cd vagrant-lamp
vagrant init</pre>


<p>Musíme upravit Vagrantfile podle následujícího předpisu (pro Vagrant 0.7).</p>

<pre class="code">Vagrant::Config.run do |config|
  # All Vagrant configuration is done here. For a detailed explanation
  # and listing of configuration options, please view the documentation
  # online.

  # Every Vagrant virtual environment requires a box to build off of.
  config.vm.box = "base"

  config.vm.forward_port("http", 80, 8080)
  config.vm.forward_port("mysql", 3306, 3306)
  config.vm.forward_port("couchdb", 5984, 5984)

  config.vm.provision :chef_solo do |chef|
     chef.cookbooks_path = "cookbooks"
     chef.json.merge!({
        :mysql =&gt; {
            :server_root_password =&gt; "root"
        }
     })
     chef.add_recipe("vagrant_main")
  end

end</pre>


<p>Vytvoříme si adresáře pro recepty a pro web.</p>

<pre class="code">mkdir cookbooks
mkdir public</pre>


<p>Do cookbooks je potřeba nakopírovat recepty pro Chef. Doporučuji si vzít z Githubu celou cookbooks repository.
git clone <a href="https://github.com/opscode/cookbooks.git">https://github.com/opscode/cookbooks.git</a></p>

<p>protože receptů je hodně, doporučuji si to dám někam mimo a nakopírovat jen potřebné recepty. Pro nás jsou to ty, které jsou v úvodu default.rb a některé navíc jako je třeba erlang pro couchdb.</p>

<p>do adresáře cookbooks jsem si nakopíroval tyto recepty z cookbooks repository.</p>

<pre>apache2
apt
couchdb
erlang
git
mysql
openssl
php</pre>


<p>Potom si vytvoříme vlastní recept, který celou akci <a href="http://www.opscode.com/chef">Chefa</a> v Vagrantu bude řídit.</p>

<pre>mkdir -p cookbooks/vagrant_main/recipes
vim default.rb</pre>


<p>Přidáme potřebné recepty</p>

<pre>require_recipe "apt"
require_recipe "apache2"
require_recipe "mysql::server"
require_recipe "php::php5"
require_recipe "git"
require_recipe "couchdb"</pre>


<p>Kromě instalace z receptů provede instalaci některý dalších balíčků v Ubuntu</p>

<pre># Some neat package (subversion is needed for "subversion" chef ressource)
%w{ debconf php5-xdebug subversion mc htop curl }.each do |a_package|
  package a_package
end</pre>


<p>Vytvoříme si testovací vývojový web.</p>

<pre>s = "dev-site"
site = {
  :name =&gt; s,
  :host =&gt; "www.#{s}.com",
  :aliases =&gt; ["#{s}.com", "dev.#{s}-static.com"]
}</pre>


<p>použije se template uložena v vagrant_main/templates/default/sites.conf.erb a příslušné proměnné</p>

<pre># Configure the development site
web_app site[:name] do
  template "sites.conf.erb"
  server_name site[:host]
  server_aliases site[:aliases]
  docroot "/vagrant/public/"
end</pre>


<p>modifikujeme si hosty</p>

<pre># Add site info in /etc/hosts
bash "info_in_etc_hosts" do
  code "echo 127.0.0.1 #{site[:host]} #{site[:aliases]} &gt;&gt; /etc/hosts"
end</pre>


<p>přidáme některé knihovny přímo z repository Subversion</p>

<pre># Retrieve webgrind for xdebug trace analysis
subversion "Webgrind" do
  repository "http://webgrind.googlecode.com/svn/trunk/"
  revision "HEAD"
  destination "/var/www/webgrind"
  action :sync
end</pre>


<p>nebo Git</p>

<pre># Retrieve adminer
git "Adminer" do
  repository "https://github.com/vrana/adminer.git"
  revision "HEAD"
  destination "/var/www/adminer/"
  action :sync
end</pre>


<p>a další</p>

<pre># Latest Zend Framework version
subversion "Zend" do
  # repository "http://framework.zend.com/svn/framework/standard/trunk/library/"
  repository "http://framework.zend.com/svn/framework/standard/tags/release-1.11.3/library/"
  revision "HEAD"
  destination "/srv/lib/php/"
  action :sync
end</pre>


<p>Potom je tu script, kterým se dá modifikovat práva pro MySQL, není problém si podobně udělat jakékoliv úpravy.</p>

<pre># Add an admin user to mysql
execute "add-admin-user" do
  command "/usr/bin/mysql -u root -p#{node[:mysql][:server_root_password]} -e \"" +
      "CREATE USER 'myadmin'@'localhost' IDENTIFIED BY 'myadmin';" +
      "GRANT ALL PRIVILEGES ON *.* TO 'myadmin'@'localhost' WITH GRANT OPTION;" +
      "CREATE USER 'myadmin'@'%' IDENTIFIED BY 'myadmin';" +
      "GRANT ALL PRIVILEGES ON *.* TO 'myadmin'@'%' WITH GRANT OPTION;\" " +
      "mysql"
  action :run
  ignore_failure true
end</pre>


<p>pro funkční port forwarding u CouchDb modifikovat konfiguraci a potřeba dát po prvním spuštění dát vargant reload aby se tato poslední změna promítla do nastavení virtuálu.</p>

<pre># Replace 127.0.0.1 bind port with 0.0.0.0 is necessary for port forwarding
execute "port-forward-couchdb" do
  command "sudo sed -i 's/127.0.0.1/0.0.0.0/g' /etc/couchdb/default.ini"
  action :run
end</pre>


<p>První spuštění pomocí</p>

<pre>vagrant up</pre>


<p>potom je potřeba pro CouchDb</p>

<pre>vagrant reload</pre>


<p>Kompletní repositář s tímto ukázkovým prostředím jsou dostupné na <a href="https://github.com/abtris/vagrant-lamp">Githubu</a>.</p>

<p>Pokud si rozbijete virtuál tak není problém začít znovu. Dáte <code>vagrant destroy</code> a potom znovu pustíte celý proces pomocí <code>vagrant up</code>.</p>

<p>Pokud se chcete přihlásit na virtuál použijte <code>vagrant ssh</code>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Zend Framework a NoSQL pro ukládání logů ve webových aplikací, díl druhý o MongoDb]]></title>
    <link href="http://blog.prskavec.net//2011/01/zend-framework-a-nosql-pro-ukladani-logu-ve-webovych-aplikaci-druhy-dil-o-mongodb/" />
    <updated>2011-01-28T00:00:00+01:00</updated>
    <id>http://blog.prskavec.net//2011/01/zend-framework-a-nosql-pro-ukladani-logu-ve-webovych-aplikaci-druhy-dil-o-mongodb</id>
    <content type="html"><![CDATA[<p>Jak už jsem psal v <a href="http://blog.prskavec.net/2010/08/zend-framework-a-nosql-pro-ukladani-logu-ve-webovych-aplikaci-dil-1-couchdb/">minulém díle o CouchDb</a> není žádný problém v použití dokumentových databází na logy. Výhodou je že se nemusíte starat o schema, což se u aplikace tohoto druhu opravdu hodí.</p>

<p>Pro napojení Zend Frameworku na logování do MongoDb musíte mít nainstalovanou MongoDb extenzi do PHP. Bez ní se bohužel neobejdete. Log writer si vytvoříte snadno pomocí extenze Zend_Log_Writer_Abstract a provedete drobné úpravy pro práci s MongoDb jak obsahuje ukázka.</p>

<pre class="code php">
/** Zend_Log_Writer_Abstract */
require_once 'Zend/Log/Writer/Abstract.php'; 
/**
 * ZendLogWriterCouchDb
 * @throws Zend_Log_Exception
 */
class App_Log_Writer_MongoDb extends Zend_Log_Writer_Abstract
{
    /**
     * Db
     * @var Mongo
     */
    private $_db;
    /**
     * Db name
     * @var string
     */
    private $_dbname;
    /**
     * Collection
     * @var string
     */
    private $_collection;
    /**
     *
     * @param array $params
     * @return void
     */
    public function __construct($options)
    {
        if (!extension_loaded('mongo')) {
            throw new Exception('The MongoDB extension must be loaded for using this logger !');
        }

        $options = $options->toArray();
        if (is_null($options)) {
            $options['host'] = "localhost";
            $options['port'] = "27017";
            $options['db'] = $dbname;
        }
        if (isset($options['user']) && isset($options['pass'])) {
            $conn = "{$options['user']}:{$options['pass']}@";
        } else {
            $conn = "";
        }
        $this->_db = new Mongo("mongodb://$conn{$options['host']}:{$options['port']}/{$options['db']}");
        $this->_dbname = $options['db'];
        $this->_collection = $options['collection'];
    }
    /**
     * @static
     * @param  $config
     * @return
     */
    static public function factory($config)                                                                                                                 
    {
        $config = self::_parseConfig($config);
        return $config;
    }
    /**
     * @param array $event
     * @return void
     */
    protected function _write($event)
    {
        $m = $this->_db;
        $m->connect();
        $c = $m->selectCollection($this->_dbname, $this->_collection);
        $c->insert($event);
    }

    
}
</pre>


<p>a tímto jste vlastně hotovy. Celý kód najdete na <a href='https://github.com/abtris/phplogger-mongodb'>githubu</a>. V ukázce je ještě samozřejmě upravený controller pro zobrazování a obsahuje možnost vytvářet testovací data.</p>

<p>MongoDb můžete nainstalovat lokálně nebo použít hosting <a href='http://mongohq.com'>mongohq.com</a>, kde základní databáze, která k testování stačí je zdarma. Potom se mi docela hodila utilita na Macu <a href="http://mongohub.todayclose.com/">Mongohub</a>, která poskytuje trochu konfortnější konzoli než webová konzole obsahující lokální instalaci. Na hostingu MongoHQ mají pěknou webovou administrační konzoli.</p>

<p>V PHP se kromě vlastní extenze dá ještě dobře použít pro Zend Framework knihovna <a href="https://github.com/coen-hyde/Shanty-Mongo">Shanty Mongo</a>, která zjednodušuje práci s Mongo Db na maximum.</p>

<p>Pokud budete chtít dělat složitější dotazy do MongoDb hodí se
<a href="http://www.mongodb.org/display/DOCS/SQL+to+Mongo+Mapping+Chart">SQL to Mongo Mapping Chart</a>.</p>

<p>Případné další tipy se nebojte napsat do komentářů.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Křest knihy 1001 tipů a triků pro PHP]]></title>
    <link href="http://blog.prskavec.net//2010/12/krest-knihy-1001-tipu-a-triku-pro-php/" />
    <updated>2010-12-23T00:00:00+01:00</updated>
    <id>http://blog.prskavec.net//2010/12/krest-knihy-1001-tipu-a-triku-pro-php</id>
    <content type="html"><![CDATA[<p>Včera se konal křest knihy 1001 tipů a triků pro PHP Jakuba Vrány, prostředí Lokády v Praze Holešovicích bylo pekně vybráno. Jako ostatní jsem přišel podpořit Jakuba a koupit si jeho knihu s podpisem. Jirka Kosek se ujal role patrona knihy a pokřtil ji šampaňským jak se patří.</p>

<p>Zlatým hřebem večera byla dražba 1 výtisku knihy, který Jakub vlastnoručně vytiskl a měl první návrh obálky a autorovy poznámku. Tento výtisk vydražili po dramatickém boji zástupci skype.</p>

<br />


<p><code><a href="http://twitter.com/spazef0rze/statuses/17736007466094592">@spazef0rze</a> Tak jsme společně s @<a rel="nofollow" href="http://twitter.com/lukashudecek">lukashudecek</a> vydražili první výtisk knihy od @<a rel="nofollow" href="http://twitter.com/jakubvrana">jakubvrana</a> <a title="#php1001" rel="nofollow" href="http://twitter.com/search?q=%23php1001">#php1001</a> za 6100 pro Paraple. K vidění bude ve Skype office.</code></p>

<br />


<p>Druhý výtisk byla verze s komentáři Davida Grudla a jeho korekturami. Tento výtisk byl opatřen polibky hlavních aktérů jak můžete vidět na videu Martina Hassmana.</p>

<p>Celková cena se vyšplhala na 10010 Kč. Celkový průběh dramatické držby jsem se snažil <a href="http://twitter.com/#search?q=php1001">twittrovat</a>, ale nebylo sto zachytit všechny příhozy.</p>

<p>Celkový výtěžek dražby Jakub věnuje <a href="http://www.paraple.cz/">kontu Paraple</a>, taktéž část z nákupu knih při autogramiádě (3 Kč z každého prodaného výtisku).</p>

<p>Knihu jsem zběžně prohlédl a vidím v ní velký potenciál. Kniha je vhodná pro všechny PHP programátory, od začínajících, kterým může složit jako dobrý návod na to co zrovna řeší. Jednotlivé tipy jsou stručné, výstižné a jdou přímo k věci. Zkušenější programátoři asi nenajdou nic objevného, ale pár tipů vás jistě jako mne zaujme také.</p>
]]></content>
  </entry>
  
</feed>

