RSS Feed

Andy Wenk Andy Wenk - Andy Wenk http://andywenk.github.io http://andywenk.github.io 2017-02-13T07:49:10+00:00 2017-02-13T07:49:10+00:00 1800 The Irreducible Components of Leadership <h1 id="paul-oneill-the-irreducible-components-of-leadership">Paul O’Neill The Irreducible Components of Leadership</h1> <p>During a discussion regarding the Hamburg based company JIMDO and them firing 75 awesome people, I was pointed to this awesome talk by <a href="https://en.wikipedia.org/wiki/Paul_H._O%27Neill">Paul O’Neill</a> about leadership (Thanks to <a href="https://twitter.com/s0enke">@s0enke</a>). Following you can find my notes I took, while I watched the <a href="https://www.youtube.com/watch?v=htLCVqaLBvo">video</a>.</p> <h4 id="a-true-leader-has-to-articulate-non-arguable-goals">A true leader has to articulate non arguable goals</h4> <h4 id="finance-should-not-be-an-objective-but-a-consequence-of-excellence">Finance should not be an objective but a consequence of excellence</h4> <h4 id="in-an-organisation-that-has-the-potential-for-greatness-the-people-in-the-organisation-can-say-every-day-without-reservation-or-hesitation-yes-to-these-three-questions">In an organisation that has the ‘potential’ for greatness, the people in the organisation can say every day without reservation or hesitation <em>yes</em> to these three questions:</h4> <ul> <li>I am treated every day with dignity and respect by everyone I encounter, without respect to my gender or my nationality or my race or my educational attainment or my rank or any other discrimination disqualifier.</li> <li>I am given the things I need - training, education, tools, encouragement - so that I can make a contribution that gives meaning to my life.</li> <li>Every day I can say someone I care about and respect, noticed I did it.</li> </ul> <p>It’s the leaders job (and it cannot be delegated to HR) to establish the conditions on an ongoing basis so every person in the institution everyday can say yes to these three propositions. These are goals and cultural characteristics.</p> <h4 id="leadership-is-not-writings-on-the-wall-its-about-acting-in-a-noticeable-way-on-the-principles-you-establish-so-that-people-begin-to-believe-that-they-are-real">Leadership is not writings on the wall, it’s about acting in a noticeable way on the principles you establish, so that people begin to believe that they are real.</h4> <h4 id="we-have-to-keep-things-personal-not-statistical">We have to keep things personal, not statistical.</h4> <h4 id="you-get-close-to-zero-in-errors-injuries-failures-by-continuous-learning-and-continuous-improvement-from-everything-going-wrong">You get close to zero (in errors, injuries, failures) by continuous learning and continuous improvement from everything going wrong.</h4> <h4 id="a-leader-needs-to-provide-running-room-for-people-to-work-to-the-theoretical-limit">A leader needs to provide running room for people to work to the theoretical limit.</h4> http://andywenk.github.io/worklife/2016/11/01/the-irreducible-components-of-leadership http://andywenk.github.io/worklife/2016/11/01/the-irreducible-components-of-leadership 2016-11-01T00:00:00+00:00 Emily Erdbeer R.I.P <p><em>So little and cute</em></p> <p><em>So cheeky and freaky</em></p> <p><em>So strong and marked</em></p> <p><br /> I miss you! <br /></p> <p><em>So curious and hilarious</em></p> <p><em>So fast and brave</em></p> <p><em>So smart and gorgeous</em></p> <p><br /> We miss you! <br /></p> <p>Nature can hurt so much. I believe you will find your peace and say hello to Duke Skelington in heaven …</p> <p><img src="http://andywenk.github.io/assets/emily.jpg" alt="Emily Erdbeer" /></p> <p>∗ September 2003 - † 14.12.2015</p> http://andywenk.github.io/2015/12/16/emily-erdbeer-rip http://andywenk.github.io/2015/12/16/emily-erdbeer-rip 2015-12-16T00:00:00+00:00 Protest: gegen den Tag der deutschen Patrioten in Hamburg <p>(German only this time … sry)</p> <p>Die aktuellen Geschehnisse in Deutschland und ganz Europa sind dramatisch. Der Zustrom der Flüchtlinge aus vom Krieg gebeutelten Ländern wie Syrien, Eritrea, Afghanistan, Irak oder Serbien (<a href="http://www.daserste.de/information/politik-weltgeschehen/mittagsmagazin/sendung/2014/woher-kommen-die-fluechtlinge-in-deutschland-100.html">Quelle</a>) nehmen hitorische Ausmaße an. Den Menschen muss geholfen werden und es liegt in unserer Verantwortung dafür zu sorgen, dass sie hier in Deutschland willkommen geheissen werden. Natürlich ist auch klar, dass ein Asylantrag geprüft werden muss.</p> <p>Leider gibt es Menschen in Deutschland, die das anders sehen. Der Rechte Mob hetzt mit Parolen gegen Asylbewerber und und “Ausländer”. Gegen diese Menschen und deren Einstellung müssen wir uns wehren. Mit gutem Beispiel geht der DGB Hamburg voran und ruft zur <a href="http://hamburg.dgb.de/themen/++co++3e822116-36b3-11e5-82ba-52540023ef1a">“Demonstration gegen den Naziaufmarsch”</a> auf.</p> <p>Weitere Informationen sind auch auf der Website <a href="http://www.keine-stimme-den-nazis.org/">“Keine Stimme den Nazis”</a> zu finden.</p> <p>In diesem Sinne - tut was - wehrt Euch!</p> <p><a href="http://www.keine-stimme-den-nazis.org" target="_blank"><img src="http://www.keine-stimme-den-nazis.org/images//logo_kein_platz_rgb.jpg" border="0" alt="" width="250" height="204" /></a></p> http://andywenk.github.io/2015/08/27/protest-gegen-den-tag-der-deutschen-patrioten-in-hamburg http://andywenk.github.io/2015/08/27/protest-gegen-den-tag-der-deutschen-patrioten-in-hamburg 2015-08-27T00:00:00+00:00 The Darknet - how to deal with todays world wide web <p>I recently finished reading the book <a href="//www.amazon.de/dp/0434023175/ref=cm_sw_r_tw_dp_pIUivb03J4ERV"><em>The Dark Net</em></a> by Jamie Bartlett. And now I am a bit confused. Read why …</p> <p>##The book</p> <p>I am not going to write a review about the book, because it is not the intention for this post. You can find various <a href="http://goo.gl/t2CJgX">reviews</a> with a bit of googling.</p> <p>Basically, Bartlett is writing about 4chan, doxxing and trolling, fascist people using the web, silkroad, childporn, porn in general, suicide and eating disorder forums and other “dark sides” of the world wide web. Reading the book is often very disturbing but also eye opening.</p> <p>I have to admit that I kind of disliked the huge chapter about <em>silk road</em> (a website where you can buy drugs online). I not only had the feeling that Bartlett was impressed by the webiste and it’s customer service, but also seems to be a proponent of sites like <em>silk road</em>. I would not say it is a bad thing in general (he stated some points like shrinking procurement crime) but it needs a very broad disussion to find a point of view.</p> <p>##Demanding the free world wide web</p> <p>Many of us are depressed what authorities know about us, when we surf the www. And a lot of us are against data mining and spying. At least we do not accept, that state authorities are collecting data from everyone just to make sure to not miss any conversations, phonecalls or metadata from potential terrorists. But some of us are going even further and are strictly against any data mining or spying in any way. We demand a free world wide web. Freedom for privacy. I am one of these people.</p> <p>To make sure that nobody is able to collect our data when surfing the web, we have some possibilities. For communication between two peers, we can encrypt our data. For example by using <a href="https://www.gnupg.org/">GnuPG</a> or <a href="https://en.wikipedia.org/wiki/S/MIME">S/Mime</a>. When surfing the Web, we can use the <a href="https://www.torproject.org/about/overview.html.en">Tor-Network</a> and its <a href="https://www.torproject.org/projects/torbrowser.html.en">Tor-Browser</a>. These techniques help to hide our data while communicating or surfing the web.</p> <p>##The confusion</p> <p>But there is a big drawback with all these techniques and our call to the authorities in stopping to spy anyone at all. “The other side” does know these tools also very well.</p> <p>If you come to the silly conclusion to buy drugs online at silk road, you can do this only when using the Tor-Network by using the Tor-Browser. You have to provide some registration information for sure. To make sure that no one will be able to follow the way back to you, all your trails are blurred. It’s your descision if you want to take the risk. I hope you will not do! (Btw - you will need to priovide a rwal address where the drugs will be sent to … wtf?).</p> <p>On the other hand, if you want to find some child porn images you have to use the same techniques to hide your data. The administrators of child-porn forums have only one thing in mind: securing the site and resources from the authorities. It is your descision if you want to search for these ressources but it is my descision, that this is in no way acceptable. Never ever!</p> <p>So here we have a problem. On one side we are able to use the techniques to hide our data from authorities spying us. Ok. Then we can use these techniques for example to harm ourselves by buying drugs and killing us in the end. But there is also the big problem, that ill people with commonly inacceptable sexual orientation are using these techniques to follow their illness.</p> <p>I don’t want to forget mentioning, that also the ill minded soldiers from the selfcalled <a href="Islamic State of Iraq and the Levant">ISIL</a> and many other terrorist groups are organising themselves with the help of the above mentioned techniques.</p> <p>##The question</p> <p>I ask myself how this should be handled. On one hand, we want to keep our data private. On the other hand we don’t want to accept annonymous abusement of people (especially women) in the world wide web. We don’t want to accept child pronography ressources in the www. We don’t want terrorist to be able to hide themselfs in the depth of the www by encrypting their communication. How can we make sure, that <em>they</em> are not able to use the techniques. This is a very tough question and the answer is most likely “we can’t”.</p> <p>Child pornography was shrinking until the world wide web was growing fastly at the end of the 90’s in the last century. Now it is almost impossible to fight against these ill people. And let’s not forget, that selling this material is also a market now. Sex sells. In any absurd way.</p> <p>##My take on this</p> <p>I have two little children. They are 5 and 8 years old. They know how to use a tablet, a smartphone and the laptop. They ask us to open pages like <a href="http://www.disney.de/">http://www.disney.de/</a> or <a href="http://www.toggo.de/">http://www.toggo.de/</a>. Wow. It’s unbeliveable how this changed so much compared to when I was a kid.</p> <p>The world wide web is not the peaceful place we think it is. When I think about my participation in the <a href="http://couchdb.apache.org">Apache CouchDB</a> project and the community we have there, I am very lucky. But we have to discuss a lot of issues in the Open Source world in general. Especially women are a target for abusement in the tech scene. Unfortunately.</p> <p>The world wide web has a dark side. A very dark side. It fears me a lot and I am very concerned about how my children will participate in this www. I am looking for ways to protect them from all dark sides (it’s still a bit early though). But this is tough.</p> <p>I am not sure what the best way is with regulation compared to a completely free world wide web. The dark sides are very dark and I think it is not acceptable and tolerable in many situations. So I think we need not only guidelines but also … something else.</p> <p>##Request for comments</p> <p>What are your thoughts on this? Do you know about the <em>dark net</em>? What are your thoughts about regulating the world wide web. Write me an email to andy@nms.de …</p> http://andywenk.github.io/2015/04/06/the-darknet-how-to-deal-with-todays-world-wide-web http://andywenk.github.io/2015/04/06/the-darknet---how-to-deal-with-todays-world-wide-web 2015-04-06T00:00:00+00:00 CouchDB Weekly News <p>Up from <a href="http://blog.couchdb.org/2014/03/">March 2014</a>, we started to release the “CouchDB Weekly News”. The reader will find all the interesting news about the development, community affairs, releases and much more of CouchDB and its community. It is an extremely helpful tool to spread the word about CouchDB. What we can say is, that the news are very well received and help the project to be more visible in the world.</p> <p>The work of aggregating all interesting stuff is done by awesome <a href="https://twitter.com/lrnrd">Lena</a>. She is supported by the <a href="http://couchdb.apache.org/#mailing-lists">Marketing Team</a> and the whole community. Thanks so much Lena for this awesome job.</p> <p>We are always looking for contributors. If you are especially interested in communiyt-marketing stuff, please subscribe to the <a href="&#109;&#097;&#105;&#108;&#116;&#111;:&#109;&#097;&#114;&#107;&#101;&#116;&#105;&#110;&#103;&#045;&#115;&#117;&#098;&#115;&#099;&#114;&#105;&#098;&#101;&#064;&#099;&#111;&#117;&#099;&#104;&#100;&#098;&#046;&#097;&#112;&#097;&#099;&#104;&#101;&#046;&#111;&#114;&#103;">marketing mailing-list</a> and drop us a note.</p> <p>And last, but not least: here are <a href="http://blog.couchdb.org/2014/12/11/couchdb-weekly-news-december-11-2014/">the latest CouchDB News</a>.</p> http://andywenk.github.io/programming/2014/12/16/couchdb-weekly-news http://andywenk.github.io/programming/2014/12/16/couchdb-weekly-news 2014-12-16T00:00:00+00:00 Screencast with Voila and convert videos for web <p>I am creating the new version of the website for a elemntary school in Hamburg called <a href="http://preview.schule-neugraben.de/">Grundschule NeugrabenOffene Ganztagsgrundschule (GBS)</a>. The responsible person for the website at this school is a teacher called Steffi and quite ok on working with websoftware. The CMS I am using here is <a href="http://refinerycms.com/">Refinery CMS</a>.</p> <p>So to make the live easy for Steffi, I decided to create very small screencasts. Well, which one to choose here. As alwasy I need simple software with good results. RTFM is boring so it has to be intuitive.</p> <p>The search results at Google told me to check out <a href="http://www.globaldelight.com/voila/">Voila</a>. It is available through Apple’s AppStore and has a price of 14.99$ at the moment. So I bought it.</p> <p>The software is dead simple and the results of the screencasts are very good not say of very high quality. BTW: I am using a Speedlink Medusa NX headset with microphone (I have that for my job when I work form home for video-web-talks). After creating a screencast you are able to upload the screencast to Google Drive, Vimeo and others. So I uploaded them to Vimeo but unfortunatley, you are just able to upload 1 HD video per week in your free account. I hade fife … sucks!</p> <p>You can also export the screencasts .mov files. I decided to do so and convert them. Good old <a href="https://www.ffmpeg.org/">ffmpeg</a> time - ding dong! The resulting files from Voila for my 4 Minute screencast is 139 MB. What I want is to share the video in a simple website like this:</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="nt">&lt;html&gt;</span> <span class="nt">&lt;head&gt;</span> <span class="nt">&lt;title&gt;</span>Video Test<span class="nt">&lt;/title&gt;</span> <span class="nt">&lt;/head&gt;</span> <span class="nt">&lt;body&gt;</span> <span class="nt">&lt;video</span> <span class="na">controls</span> <span class="na">style=</span><span class="s">"width:700px"</span><span class="nt">&gt;</span> <span class="nt">&lt;source</span> <span class="na">src=</span><span class="s">"Schule-Neugraben-CMS-Bild-einfuegen.mp4"</span> <span class="na">type=</span><span class="s">"video/mp4"</span><span class="nt">/&gt;</span> <span class="nt">&lt;source</span> <span class="na">src=</span><span class="s">"Schule-Neugraben-CMS-Bild-einfuegen.webm"</span> <span class="na">type=</span><span class="s">"video/webm"</span><span class="nt">/&gt;</span> <span class="nt">&lt;/video&gt;</span> <span class="err">&lt;</span>/body <span class="nt">&lt;/html&gt;</span> </code></pre> </div> <p>I need to convert the .mov file to an .mp4 file. I don’t want to crop or change anything. The commandline looks like this:</p> <div class="highlighter-rouge"><pre class="highlight"><code>ffmpeg -i Schule-Neugraben-CMS-Bild-einfuegen.mov Schule-Neugraben-CMS-Bild-einfuegen.mp4 </code></pre> </div> <p>While converting, ffmpeg is using the H.264/MPEG-4 AVC codec. You could also add the parameter</p> <div class="highlighter-rouge"><pre class="highlight"><code>-q:a [quality, INTEGER] </code></pre> </div> <p>for audio quality or</p> <div class="highlighter-rouge"><pre class="highlight"><code>-q:v [quality, INTEGER] </code></pre> </div> <p>for video quality. I ommited both because I wanted the best result.</p> <p>The resulting .mp4 file is now 15 MB in size and the quality is still really good. The next step is to convert the .mp4 file into a .webm file. This is a format resulting of Google’s <a href="http://en.wikipedia.org/wiki/VP8">vp8 codec</a> and this is done with <code class="highlighter-rouge">libvpx</code>. If you don’t have it already compiled into ffmpeg, you can simply reinstall ffmpeg with homebrew like so:</p> <div class="highlighter-rouge"><pre class="highlight"><code>brew reinstall ffmpeg --with-libvpx </code></pre> </div> <p>Find more info about that at <a href="https://developer.mozilla.org/en-US/Apps/Build/Audio_and_video_delivery/H.264_support_in_Firefox">Mozillas H.264 support in Firefox site at MDN</a> and at <a href="http://www.webmproject.org/">http://www.webmproject.org</a>.</p> <p>The commandline looks like this:</p> <div class="highlighter-rouge"><pre class="highlight"><code>ffmpeg -i Schule-Neugraben-CMS-Bild-einfuegen_2.mp4 -strict -2 Schule-Neugraben-CMS-Bild-einfuegen.webm </code></pre> </div> <p>The flag <code class="highlighter-rouge">-strict -2</code> is neccessary, because ffmpeg doesn’t let you convert the file: <em>The encoder ‘vorbis’ is experimental but experimental codecs are not enabled, add ‘-strict -2’ if you want to use it.</em> Ok - as you like!</p> <p>The resulting .webm file is 9.4 MB in size. That’s cool. And now you are able to visit the website shown above. We have two different files for the HTML5 video tag what will support most browsers. And if someone comes with Internet Explorer … well - I personally don’t care.</p> <p>One note: converting the .mp4 file to .webm takes really long!</p> http://andywenk.github.io/programming/2014/11/16/screencast-with-voila-and-convert-videos-for-web http://andywenk.github.io/programming/2014/11/16/screencast-with-voila-and-convert-videos-for-web 2014-11-16T00:00:00+00:00 Reminder: Ruby private behaves differently <p>Assume you have the following dead simple class:</p> <div class="highlighter-rouge"><pre class="highlight"><code>class Doc private def say "andy" end end </code></pre> </div> <p>We agree, that the method <code class="highlighter-rouge">say</code> is marked private and cannot be called like so:</p> <div class="highlighter-rouge"><pre class="highlight"><code>&gt; doc = Doc.new &gt; doc.say NoMethodError: private method `say` called for #&lt;Doc:0x007f8c93087c18&gt; from (irb):22 </code></pre> </div> <p>Ok. But you already know, that this does not mean, that you can’t access <code class="highlighter-rouge">say</code> from outside right? No? Here is the prove:</p> <div class="highlighter-rouge"><pre class="highlight"><code>&gt; doc = Doc.new &gt; doc.send(:say) =&gt; "andy" </code></pre> </div> <p>Oh!</p> <p>I assume you have learned, that you can’t access private methods from a child class. That’s true for many programming languages. But not in Ruby. See this example:</p> <div class="highlighter-rouge"><pre class="highlight"><code>class TextDoc &lt; Doc def spoken_words say end end </code></pre> </div> <p>So we want to call <code class="highlighter-rouge">say</code>, what is declared <code class="highlighter-rouge">private</code> in the class <code class="highlighter-rouge">Doc</code> in <code class="highlighter-rouge">spoken_words</code>. Does this work?</p> <div class="highlighter-rouge"><pre class="highlight"><code>&gt; text_doc = TextDoc.new &gt; text_doc.spoken_words =&gt; "andy" </code></pre> </div> <p>Oh! Wait. WTF?</p> <p>The point in Ruby is, that the language does not prevent you from doing things if you really want to. It is your responsibility to deal with it - not the language implementors. Having these possibilities opens a lot of doors not only in Ruby’s meta-programming power, but helps also to write less and most importantly readable code. Visibility issues? It’s your responsibility as a developer to take care of.</p> http://andywenk.github.io/programming/2014/11/13/reminder-ruby-private-behaves-differently http://andywenk.github.io/programming/2014/11/13/reminder-ruby-private-behaves-differently 2014-11-13T00:00:00+00:00 Fight Internet Slowdown <p>As you have entered my blog, you may have noticed an annoying loading icon. US Internet providers want to slow down internet connections for profit. We have to fight against that and keep the Internet free and neutral.</p> <p>Check out more infos at <a href="https://www.battleforthenet.com/sept10th">https://www.battleforthenet.com/sept10th</a>.</p> <p><img src="http://andywenk.github.io/assets/internet-slowdown.png" alt="Internet Slowdown" /></p> http://andywenk.github.io/2014/09/10/fight-internet-slowdown http://andywenk.github.io/2014/09/10/fight-internet-slowdown 2014-09-10T00:00:00+00:00 Duke Skelington R.I.P <p><em>You may say, that’s the nature of things</em></p> <p>  … but it hurts all the same</p> <p><em>You may say, you did your best to avoid pain</em></p> <p>  … but it hurts all the same</p> <p><em>You knew that the day will come where you need to be strong</em></p> <p>  … but it hurts all the same</p> <p><em>You might say, “it’s just a cat in the end”</em></p> <p>  … but you are wrong</p> <p><em>He was my friend!</em></p> <p><em>He was my family!</em></p> <p><em>He was my hero!</em></p> <p><img src="http://andywenk.github.io/assets/duke.png" alt="Duke Skelington" /></p> <p><strong>R.I.P Duke Skelington - I miss you!</strong></p> <p>∗ 25.05.2000 - † 11.08.2014</p> http://andywenk.github.io/2014/08/11/duke-skelington-rip http://andywenk.github.io/2014/08/11/duke-skelington-rip 2014-08-11T00:00:00+00:00 Ruby: create a Hash from Arrays <p>Ruby has a very beatutiful expressiveness and offers a great standard library. This helps a lot when dealing with data structures. Especially when you have to convert, merge or combine Arrays and Hashes. This post is showing just a little example out of the big area of possibilities.</p> <h2 id="the-target">The target</h2> <p>One thing we likely stumble upon when creating data structures is the task to create a <code class="highlighter-rouge">Hash</code> from two Arrays where one <code class="highlighter-rouge">Array</code> holds the <code class="highlighter-rouge">keys</code> and the other one the <code class="highlighter-rouge">values</code> of the resulting <code class="highlighter-rouge">Hash</code>. Based upon our example Arrays, one result could look like this:</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="p">{</span><span class="w"> </span><span class="nt">"Verena"</span><span class="w"> </span><span class="err">=&gt;</span><span class="w"> </span><span class="nt">"reading"</span><span class="err">,</span><span class="w"> </span><span class="nt">"Kiana"</span><span class="w"> </span><span class="err">=&gt;</span><span class="w"> </span><span class="nt">"swimming"</span><span class="err">,</span><span class="w"> </span><span class="nt">"Naya"</span><span class="w"> </span><span class="err">=&gt;</span><span class="w"> </span><span class="nt">"painting"</span><span class="w"> </span><span class="err">}</span><span class="w"> </span></code></pre> </div> <p>Or even:</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="p">{</span><span class="w"> </span><span class="nt">"Verena"</span><span class="w"> </span><span class="err">=&gt;</span><span class="w"> </span><span class="nt">"rock"</span><span class="err">,</span><span class="w"> </span><span class="nt">"Kiana"</span><span class="w"> </span><span class="err">=&gt;</span><span class="w"> </span><span class="err">[</span><span class="w"> </span><span class="err">[0]</span><span class="w"> </span><span class="nt">"folk"</span><span class="err">,</span><span class="w"> </span><span class="err">[1]</span><span class="w"> </span><span class="nt">"disco"</span><span class="w"> </span><span class="err">],</span><span class="w"> </span><span class="nt">"Naya"</span><span class="w"> </span><span class="err">=&gt;</span><span class="w"> </span><span class="nt">"metal"</span><span class="w"> </span><span class="err">}</span><span class="w"> </span></code></pre> </div> <p>The following sections will describe how we can create these data structures.</p> <h2 id="the-data">The data</h2> <p>We have three simple Arrays with the following structure:</p> <div class="highlighter-rouge"><pre class="highlight"><code>names = %w(Verena Kiana Naya) [ [0] "Verena", [1] "Kiana", [2] "Naya" ] hobbies = %w(reading swimming painting) [ [0] "reading", [1] "swimming", [2] "painting" ] music = ['rock', %w(folk disco), 'metal'] [ [0] "rock", [1] [ [0] "folk", [1] "disco" ], [2] "metal" ] </code></pre> </div> <p>These Arrays are the base for all subsequent steps to create our <code class="highlighter-rouge">Hash</code>.</p> <h2 id="combine-data-with-the-arrayzip-method">Combine data with the <code class="highlighter-rouge">Array#zip</code> method</h2> <p>From the <a href="http://www.ruby-doc.org/core-2.1.2/Array.html#method-i-zip">documentation</a> &gt; Converts any arguments to arrays, then merges elements of self with &gt; corresponding elements from each argument. …</p> <p>So when using our data structures, we can do something like this:</p> <div class="highlighter-rouge"><pre class="highlight"><code>names.zip(hobbies) [ [0] [ [0] "Verena", [1] "reading" ], [1] [ [0] "Kiana", [1] "swimming" ], [2] [ [0] "Naya", [1] "painting" ] ] </code></pre> </div> <p>As you can see, <code class="highlighter-rouge">Array#zip</code> is creating a new Array from our two Arrays <code class="highlighter-rouge">name</code> and <code class="highlighter-rouge">hobbies</code>. The resulting Array consists of pairs from <code class="highlighter-rouge">name[0] -&gt; hobbies[0]</code>, <code class="highlighter-rouge">name[1] -&gt; hobbies[1]</code> and so on. If no corresponding value can be found, <code class="highlighter-rouge">nil</code> will be inserted in the resulting Array.</p> <p>The <code class="highlighter-rouge">zip</code> method is very helpful for creating data structures as we will see when we will create a Hash.</p> <h2 id="a-flat-array-from-a-nested-array-with-arrayzip">A flat Array from a nested Array with <code class="highlighter-rouge">Array#zip</code></h2> <p>From the <a href="http://www.ruby-doc.org/core-2.1.2/Array.html#method-i-flatten">documentation</a></p> <blockquote> <p>Returns a new array that is a one-dimensional flattening of self (recursively).</p> </blockquote> <p>The resulting Array of Arrays created with the <code class="highlighter-rouge">Array#zip</code> method is not yet in the correct form to be able to throw it into our resulting <code class="highlighter-rouge">Hash</code>. We have to convert it into a <code class="highlighter-rouge">one dimensional Array</code> because later we will create the <code class="highlighter-rouge">key</code> - <code class="highlighter-rouge">value</code> pairs like this:</p> <div class="highlighter-rouge"><pre class="highlight"><code>key0 = Array[0] value1 = Array[1] key1 = Array[2] value1 = Array[3] </code></pre> </div> <p>I think you got the idea. <code class="highlighter-rouge">Array#flatten</code> will help us to get the job done. It is as simple as this:</p> <div class="highlighter-rouge"><pre class="highlight"><code>names.zip(hobbies).flatten [ [0] "Verena", [1] "reading", [2] "Kiana", [3] "swimming", [4] "Naya", [5] "painting" ] </code></pre> </div> <p>That was easy. Now let’s see how we create the final <code class="highlighter-rouge">Hash</code> in the next section.</p> <h2 id="reaching-the-target-creating-the-hash-from-arrays">Reaching the target: creating the <code class="highlighter-rouge">Hash</code> from <code class="highlighter-rouge">Arrays</code></h2> <p>We are nearly done. In the last section we saw, how to create a flattened Array. This Array has the correct form to throw it into our Hash. So let’s do it:</p> <div class="highlighter-rouge"><pre class="highlight"><code>Hash[names.zip(hobbies).flatten] (irb):47: warning: wrong element type String at 0 (expected array) (irb):47: warning: ignoring wrong elements is deprecated, remove them explicitly (irb):47: warning: this causes ArgumentError in the next release (irb):47: warning: wrong element type String at 1 (expected array) </code></pre> </div> <p>Oh WTF? That is not the expected result. Why is this?</p> <p>The problem is, that a Hash expects to receive a list of arguments. And here comes the <code class="highlighter-rouge">splat</code> operator <code class="highlighter-rouge">*</code> into play. It is able to convert a list into a group of parameters and is able to fill an Array with a group of parameters. Following we look at some examples.</p> <p><em>Convert a Hash into an Array</em></p> <div class="highlighter-rouge"><pre class="highlight"><code>hash = *{'Andy' =&gt; 'Daddy'} [ [0] [ [0] "Andy", [1] "Daddy" ] ] </code></pre> </div> <p><em>Convert a (flat) Array into a Hash</em></p> <div class="highlighter-rouge"><pre class="highlight"><code>Hash[*n.flatten] { "Andy" =&gt; "Daddy" } </code></pre> </div> <p>Interesting is to examing the result with the <code class="highlighter-rouge">class</code> method:</p> <div class="highlighter-rouge"><pre class="highlight"><code>hash = {'Andy' =&gt; 'Daddy'}.class =&gt; Hash hash = *{'Andy' =&gt; 'Daddy'}.class =&gt; [Hash] </code></pre> </div> <p>As you can see, the second one is a <code class="highlighter-rouge">Hash</code> in a list (Array).</p> <p>You can also do other cool stuff with the splat operator. Please have a look at the <a href="http://4loc.wordpress.com/2009/01/16/the-splat-operator-in-ruby/">4loc Blog</a> for more details.</p> <h2 id="but-now-the-final-hash">But now: the final Hash</h2> <p>After we understood why the error occured and know how to circumvent it, we are finally able to create our <code class="highlighter-rouge">Hash</code>:</p> <div class="highlighter-rouge"><pre class="highlight"><code>Hash[*names.zip(hobbies).flatten] { "Verena" =&gt; "reading", "Kiana" =&gt; "swimming", "Naya" =&gt; "painting" } </code></pre> </div> <p>Woot! That’s the result we expected. Cool. But what if the <code class="highlighter-rouge">hobbies</code> data structure would have nested Arrays? Let’s see what happens, when we use the <code class="highlighter-rouge">music</code> Array instead of the <code class="highlighter-rouge">hobbies</code> Array:</p> <div class="highlighter-rouge"><pre class="highlight"><code>Hash[*names.zip(music).flatten] ArgumentError: odd number of arguments for Hash from (irb):79:in `[]' from (irb):79 from /Users/andwen/.rvm/rubies/ruby-2.0.0-p353/bin/irb:12:in `&lt;main&gt;' </code></pre> </div> <p>Hm - that did not work. Ruby does not know what to do with the <code class="highlighter-rouge">not flat</code> data structure of <code class="highlighter-rouge">music</code>. We need to create the Hash a bit differently:</p> <div class="highlighter-rouge"><pre class="highlight"><code>result = {} Hash[names.zip(music).each {|a,b| result[a] = b }] { "Verena" =&gt; "rock", "Kiana" =&gt; [ [0] "folk", [1] "disco" ], "Naya" =&gt; "metal" } </code></pre> </div> <p>That did the trick. Please note that this is working for an Array one level deep nested. I leave it to you to also find a solution for n-level deep nested Arrays :-) .</p> <h2 id="further-info-for-array-and-hash">Further info for Array and Hash</h2> <p>Dealing with Arrays and Hashes is daily business for developers. That for sure also counts for Rubyists. You should definitely dive into the documentation for the <a href="http://www.ruby-doc.org/core-2.1.2/Array.html">Array</a> and <a href="http://www.ruby-doc.org/core-2.1.2/Hash.html">Hash</a> Classes included in the Ruby standard library.</p> <h2 id="conclusion">Conclusion</h2> <p>In this post we examined how to convert two Arrays with simple data structures in a Hash with a <code class="highlighter-rouge">key - value data structure</code>. This is very helpful when dealing with data and we have seen, that Ruby offers good solutions to handle these tasks.</p> <p>How are you creating similar data structures? I am curious and would love to receive a message from you … simply send it to <a href="&#109;&#097;&#105;&#108;&#116;&#111;:&#097;&#110;&#100;&#121;&#064;&#110;&#109;&#115;&#046;&#100;&#101;">&#097;&#110;&#100;&#121;&#064;&#110;&#109;&#115;&#046;&#100;&#101;</a>.</p> <p>##UPDATE</p> <p>Thanks to <a href="https://twitter.com/nosuchthingas2">Nathan Wallace</a> who pointed out that you can do this since <a href="http://ruby-doc.org/core-2.1.0/Array.html#method-i-to_h">Ruby 2.1</a></p> <div class="highlighter-rouge"><pre class="highlight"><code>names.zip(music).to_h { "Verena" =&gt; "rock", "Kiana" =&gt; [ [0] "folk", [1] "disco" ], "Naya" =&gt; "metal" } </code></pre> </div> http://andywenk.github.io/programming/2014/06/27/ruby-create-a-hash-from-arrays http://andywenk.github.io/programming/2014/06/27/ruby-create-a-hash-from-arrays 2014-06-27T00:00:00+00:00 Rack middleware in Rails to recode the URL <p>I have created the <a href="https://www.qraex.de">Qräx online shop</a> for a good friend. During the last days, a lot of exceptions were thrown. As the application is quite small I do not use a bug tracker but send exception emails to my mailbox. Keep it simple.</p> <p>The content of the exception email is looking like this:</p> <div class="highlighter-rouge"><pre class="highlight"><code>Fehler in Qraex production: PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "" LINE 1: ...artridge_id FROM "printer_cartridges" WHERE (printer_id='') ^ : SELECT cartridge_id FROM "printer_cartridges" WHERE (printer_id='') * Aktion: inkshop#show_qraex_products * Client: 37.16.72.124 * Session: * Request: /tintenshop/tintenstrahl_drucker_produkte/hp/PSC/HP-56/PSC+2510?page=2 * Knoten: nms02 * Prozess: 23810 </code></pre> </div> <p>I wondered where the URL is coming from because the <em>+</em> sign in the URL should be a <em>%20</em> what is a blank.</p> <p>The Client is nearly always the same. So I checked the webserver log files and recognized, that it is a bot from <a href="http://archivethe.net">http://archivethe.net</a>. The log entries are looking like this:</p> <div class="highlighter-rouge"><pre class="highlight"><code>37.16.72.124 - - [08/Jun/2014:08:42:37 +0200] "GET /tintenshop/tintenstrahl_drucker/hp/OfficeJet+D,+E,+G,+H HTTP/1.1" 500 5493 "-" "Mozilla/5.0 (compatible; memorybot/1.20.71 +http://archivethe.net/en/index.php/about/internet_memory1 on behalf of DNB)" "-" </code></pre> </div> <h2 id="what-to-do">What to do?</h2> <p>I was thinking about where the bot found the URL’s and I understood, that they have been received from the <a href="https://www.qraex.de/sitemap.xml">sitemap.xml</a>. A short check showed, that the sitemap has entries like this:</p> <div class="highlighter-rouge"><pre class="highlight"><code>&lt;url&gt; &lt;loc&gt; https://www.qraex.de/tintenshop/anfrage_stellen/drucker/Hewlett+Packard,+OfficeJet+7100 &lt;/loc&gt; &lt;priority&gt;0.0004&lt;/priority&gt; &lt;/url&gt; </code></pre> </div> <p>Ok - my fault. I guess I made a mistake when generating the sitemap. That means blocking the IP from the bot would be the wrong path.</p> <h2 id="fixing-the-problem">Fixing the problem</h2> <p>The Rails application is using the part from the URL to make a lookup to the database. But the <em>+</em> sign in there is completely wrong. As mentioned before it should be <em>%20</em>. I decided to find a way to recode the URL for each GET request.</p> <p>Doing this in the webserver is possible but not too sexy. The other idea would be to use a gem for rewriting the URL. Nah, to heavy. The simplest possible solution is to write a very small Rack middleware and put it into the Rails Middleware stack.</p> <h2 id="the-code">The code</h2> <p>I will not dig deeper into <a href="http://rack.github.io/">Rack</a> and the <a href="http://guides.rubyonrails.org/rails_on_rack.html">Rails middleware</a> stack. What you have to know is, that the middleware has to be put together in a special order. If my middleware would be included too early, the application would crash.</p> <p>I found out that a good place is after <em>Rack::ETag</em>. I called the middleware <em>RecodeUrl</em>. When checking the existing middleware, you will see this list:</p> <div class="highlighter-rouge"><pre class="highlight"><code>use ActionDispatch::Static use Rack::Lock use #&lt;ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x0000010ab81ae0&gt; use Rack::Runtime use Rack::MethodOverride use ActionDispatch::RequestId use Rails::Rack::Logger use ActionDispatch::ShowExceptions use ActionDispatch::DebugExceptions use BetterErrors::Middleware use ActionDispatch::RemoteIp use ActionDispatch::Reloader use ActionDispatch::Callbacks use ActiveRecord::ConnectionAdapters::ConnectionManagement use ActiveRecord::QueryCache use ActionDispatch::Cookies use ActionDispatch::Session::CacheStore use ActionDispatch::Flash use ActionDispatch::ParamsParser use ActionDispatch::Head use Rack::ConditionalGet use Rack::ETag use RecodeUrl use ActionDispatch::BestStandardsSupport use Warden::Manager use Bullet::Rack use MetaRequest::Middlewares::MetaRequestHandler use MetaRequest::Middlewares::Headers use MetaRequest::Middlewares::AppRequestHandler run Qraex::Application.routes </code></pre> </div> <p>The code for the middleware is a simple Ruby class and is placed in lib/recode_url.rb:</p> <div class="highlighter-rouge"><pre class="highlight"><code>class RecodeUrl def initialize(app, options = {}) @app = app end def call(env) env['PATH_INFO'] = env['PATH_INFO'].gsub('+','%20') if env['REQUEST_METHOD'] == 'GET' @app.call(env) end end </code></pre> </div> <p>The <em>initialize</em> and <em>call</em> methods are Rack standard and have to be there (see the documentation). Every attribute is located in the Hash <em>env</em>. So waht I do with the code above is simply changing the <em>+</em> sign to <em>%20</em> in <em>env[‘PATH_INFO’]</em> if it is a <em>GET</em> request. Nothing more.</p> <p>To activate the middleware, an entry in <em>config/application.rb</em> is neccessary:</p> <div class="highlighter-rouge"><pre class="highlight"><code>module Qraex class Application &lt; Rails::Application [... other config settings ommited] require 'recode_url' config.middleware.insert_after Rack::ETag, RecodeUrl end end </code></pre> </div> <p>When the server is started and the URL</p> <div class="highlighter-rouge"><pre class="highlight"><code>http://localhost:3000/tintenshop/tintenstrahl_drucker/hp/Business+InkJet </code></pre> </div> <p>is called, it will be recoded to</p> <div class="highlighter-rouge"><pre class="highlight"><code>http://localhost:3000/tintenshop/tintenstrahl_drucker/hp/Business%20InkJet </code></pre> </div> <p>internally and everything is fine.</p> <h2 id="conclusion">Conclusion</h2> <p>Rack middleware is an extremely simple but powerfull tool to get special jobs done. Every Rails developer should understand, that Rails is a Rack application. And furthermore most of the Ruby web-frameworks like <a href="http://www.sinatrarb.com/">sinatra</a> and <a href="http://www.padrinorb.com/">padrino</a> are Rack applications too. The great advantage is the fact, that it is possible to hook into the HTTP requests before the Rails stack is gone through.</p> http://andywenk.github.io/rails/2014/06/11/rack-middleware-in-rails-to-recode-the-url http://andywenk.github.io/rails/2014/06/11/rack-middleware-in-rails-to-recode-the-url 2014-06-11T00:00:00+00:00 Bundler problem with git: source <p>Starting with a fresh Rails application I stumbled upon a confusing problem. I started to integrate the gem <a href="https://github.com/melvinsembrano/cms-fortress">cms-fortress</a> as an extension for the quite cool <a href="https://github.com/comfy/comfortable-mexican-sofa">ComfortableMexicanSofa</a> CMS. The integration in the Gemfile looked like this (the source is now our <a href="https://github.com/sumcumo/cms-fortress">fork</a> on github):</p> <div class="highlighter-rouge"><pre class="highlight"><code>gem 'cms-fortress', :git =&gt; 'git@github.com:sumcumo/cms-fortress.git', :branch =&gt; 'master' </code></pre> </div> <p>Straight forward, but Rails was not able to use the gem. The error message when starting Rails was:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/p/s/kenny git:cms-fortress ❯❯❯ rails s git@github.com:sumcumo/cms-fortress.git (at master) is not yet checked out. Run `bundle install` first. git@github.com:sumcumo/cms-fortress.git (at master) is not yet checked out. Run `bundle install` first. no ruby in PATH/CONFIG =&gt; Booting Puma [...] </code></pre> </div> <h2 id="bundler-config-files">Bundler config files</h2> <p>After trying out various possible solutions with no luck, I thought it must have to do with a setting in a config file. Basically there are two config files. One is <em>~/.bundle/config</em> and the other one is in <em>RAILS_ROOT/.bundle/config</em>. Actually nothing obviously wrong in there. Removing them did not help.</p> <h2 id="bundler-cache">Bundler cache</h2> <p>There are various places where bundler is caching gems. One is <em>~/.gems/cache/bundler/</em>, another is <em>$GEM_HOME/cache/bundler/</em> where <em>$GEM_HOME</em> is the directory when using <em>rvm</em> and <em>gemsets</em> and finally there is <em>RAILS_ROOT/vendor/cache/</em>. I am not sure when and if I cleared the cache directories. But it did not help anyway.</p> <h2 id="gemfilelock">Gemfile.lock</h2> <p>Bundler is writing all used gems and it’s dependencies into the <em>Gemfile.lock</em> file. There are circumstances, where you may want to delete that file if you have some strange behaviour like not being able to install gems or during a deployment process with capistrano. No problems arise when you delete the file because when running <em>bundle install</em> it will be recreated. Deleteing the file and recreating it did not help either.</p> <h2 id="more-confusion">More confusion</h2> <p>After several attempts to fix the problem, checking out the <a href="http://bundler.io/v1.6/man/bundle.1.html">bundler documentation</a>, deleting the gemset with <em>rvm gemset delete GEMSET_NAME</em> and finally removing the Ruby version completely and reinstalling it, I was stuck. My attempts to find a solution at Google was also not fruitful … beside one SO entry:</p> <p><a href="http://stackoverflow.com/questions/22554365/bundle-doesnt-want-to-install-a-gem-not-yet-checked-out">Bundle doesn’t want to install a gem (not yet checked out)</a></p> <p>Andreas Lyngstad pointed to the <a href="https://github.com/bundler/bundler/blob/master/ISSUES.md">Bundler issue page</a> and it’s troubleshooting section. It does recommend to fire these commands:</p> <div class="highlighter-rouge"><pre class="highlight"><code># remove user-specific gems and git repos rm -rf ~/.bundle/ ~/.gem/bundler/ ~/.gems/cache/bundler/ # remove system-wide git repos and git checkouts rm -rf $GEM_HOME/bundler/ $GEM_HOME/cache/bundler/ # remove project-specific settings rm -rf .bundle/ # remove project-specific cached gems and repos rm -rf vendor/cache/ # remove the saved resolve of the Gemfile rm -rf Gemfile.lock # uninstall the rubygems-bundler and open_gem gems rvm gemset use global # if using rvm gem uninstall rubygems-bundler open_gem # try to install one more time bundle install </code></pre> </div> <p>I did follow the recommendation and deleted and recreated the gemset again in addition. This is done with:</p> <div class="highlighter-rouge"><pre class="highlight"><code>rvm gemset delete GEMSET_NAME rvm use ruby-2.1.1@GEMSET_NAME --create </code></pre> </div> <p>Then I ran <em>bundle install</em> and afterwards <em>rails s</em> … but:</p> <div class="highlighter-rouge"><pre class="highlight"><code>Warning: You're using Rubygems 2.0.14 with Spring. Upgrade to at least Rubygems 2.1.0 and run `gem pristine --all` for better startup performance. Could not find json-1.8.1 in any of the sources Run `bundle install` to install missing gems. </code></pre> </div> <p>This is completely nonsens because I am using rubgygems 2.2.2 what is confirmed by the following check:</p> <div class="highlighter-rouge"><pre class="highlight"><code>gem -v 2.2.2 </code></pre> </div> <p>Strangely, when stepping out of the directory and reentering again and trying to start the application … ta ta … everything worked. Uh …</p> <h2 id="conclusion">Conclusion</h2> <p>My conslusion is, that there have been basically two problems. First, bundler is installed globally and is used with the global configuration. And in addition, there is the rubygems-bundler gem what imho caused problems. Because when examining the <a href="https://github.com/mpapis/rubygems-bundler">README</a> of the gem you will find</p> <blockquote> <p><em>Generally, this gem is not needed on RubyGems &gt;= 2.2.0.</em></p> </blockquote> <p>That means removing the gem did help. Furthermore there must have been some sttings or cached stuff what was forcing these problems. Removing everything did help at the end … I think and hope.</p> <p>But why in the world did the above output say:</p> <blockquote> <p><em>Warning: You’re using Rubygems 2.0.14 …</em></p> </blockquote> <p>I suspect that there is a mismatch when creating a fresh gemset with the used rubygems version. And this was resolved, when reinitialising the gemset with</p> <blockquote> <p><em>rvm use ruby-2.1.1@GEMSET_NAME</em></p> </blockquote> <p>To be honest, I have no clue why that problem occured.</p> <h2 id="i-hope-it-helps-at-least">I Hope it helps at least</h2> <p>Unfortunately this post is not explaining why the problems occured. I have some ideas but am not entirely sure. At least, I could find a way to solve the problem for me and hope that it will solve also issues for some other folks also. It’s unfortunate, that it feels a bit like a black box with no way to shine into it …</p> <p>Thanks also to my fellow colleague Moritz for helping investigating this.</p> http://andywenk.github.io/rails/2014/06/11/bundler-problem-with-git-source http://andywenk.github.io/rails/2014/06/11/bundler-problem-with-git-source 2014-06-11T00:00:00+00:00 Invitation to become an ASF member <p>As you may know, I am very involved in the <a href="http://couchdb.apache.org">Apache CouchDB</a> project. I really like contributing because the community is cool and CouchDB is an awesome piece of software.</p> <p>Recently the invitation to become an <em>Apache Software Foundation Member</em> dropped into my mailbox. Wow! I am relly honoured and I accepted the invitation. Thanks a lot to <a href="https://twitter.com/nslater">Noah Slater</a> who suggested me and started the election.</p> <h2 id="the-asf">The ASF</h2> <p>So what is a member? To be honnest, I did not know when I became a Apache CouchDB committer last November. The ASF has a quite simple structure:</p> <p>###Users</p> <p>Everyone who is using ASF software</p> <p>###Contributors</p> <p>People who are contributing to a project by sending code patches, writing blog posts or articles. They do not have further rights to commit code for example.</p> <p>###Committers</p> <p>When someone is contributing a lot, he will eventually be invited to become a committer and will be granted access rights to infrastructure used. We call that simply <em>commit bits</em>.</p> <p>###PMC member</p> <p>Each project has a Project Management Committee. Committers will be asked to join the PMC when they continuously committ to the project and help to organise the project affairs.</p> <p>###Project Chair</p> <p>Every project has a <strong>chair</strong>. The chair will automatically become a member because he should be able to state his opinion in the ASF affairs.</p> <p>###ASF member</p> <p>The ASF members are helping to control the ASF affairs. So members are not bound to a specific project but are an global instance. Mostly, they contribute to more projects.</p> <p>###ASF board</p> <p>The board is overseeing the ASF activities and is elected by the members annually.</p> <p>This is just a simple summary of the ASF structure. There also many processes and bylaws. If interested, you can find a lot of information at the <a href="http://apache.org/">ASF website</a>. Or - simply ask me :)</p> <p>I am really looking forward to contribute to the ASF. I think the ASF is a great place for Open Source Software and I encourage you to check out the website. I am sure you are already using ASF software. Did you know, that 60% of the websites you are surfing on are run with a <a href="http://httpd.apache.org/">Apache Webserver</a> and that the <a href="https://www.openoffice.org/">Open Source Office Software</a> you are likely using is also an ASF project?</p> http://andywenk.github.io/asf/2014/06/02/invitation-to-become-an-asf-member http://andywenk.github.io/asf/2014/06/02/invitation-to-become-an-asf-member 2014-06-02T00:00:00+00:00 Why is the Ruby community jog around? <p>These days, there are many blog posts we can read about why the Ruby community is split into parts. I am a bit surprised about this, especially about the way how folks are talking about this.</p> <p>##The split</p> <p>Some folks say, that there is a Rails community and a Ruby community. Adam Hawkins (<a href="http://twitter.com/adman65">@adam65</a>) for example is speaking of a <a href="http://hawkins.io/2014/05/fragmentation_in_the_ruby_community/">“Fragmentation in the Ruby Community”</a>:</p> <blockquote> <p>The Ruby community is fragmenting. The community needs new leadership.</p> </blockquote> <p>I have to admit, that I am not attending Ruby or Rails conferences (unfortunately) and do not really have direct contact to the community. But I read a lot from and about it and follow many talks.</p> <p>My feeling is, that there is no gap and also no need for new leadership but the need for a bit more selfconfidence. How in the world can one speak of a “leader” in an open source community? I am afraid here is a bit of misunderstanding (maybe also on my side).</p> <p>##DHH is the bad guy!</p> <p>Really? Why? As far as I followed the discussions, it started all with DHH’s <a href="https://www.youtube.com/watch?v=9LfmrkyP81M">keynote at this years Railsconf 2014</a>. I watched the keynote and I thought it was a good one. Even when I don’t agree with everything DHH said, I think it was a good one because DHH stated a clear position about how he is developing software. This is focusing. Yes! But not selling … .</p> <p>In my humble opinion, it’s a good thing. You are not forced to share DHH’s opinion in any way. You should find your own point of view and speak about it - like <a href="http://lucaguidi.com/2014/05/19/rails-is-not-dead.html">Luca Guidi did</a>. So why is DHH the bad guy? I don’t follow that.</p> <p>Side Note: I also read that some <a href="http://codon.com/the-dhh-problem">people are not happy about the language DHH is using</a>. I can understand that and I think also it is questionable. In the <a href="http://couchdb.apache.org">CouchDB community</a>, we are in the process of creating the <a href="https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=41812010">“Project Code of Conduct and Diversity Statement”</a>. This is for a good reasen because we want to make clear, that we expect people to behave in a “empathetic, welcoming, friendly and patient” way in our community. DHH’s language in his talk would not be appropriate.</p> <p>UPDATE: I just found the blog post <a href="http://www.ugtastic.com/dhh-cult-personality-problem">http://www.ugtastic.com/dhh-cult-personality-problem</a> and I fully chare the opinion of Mike Hall.</p> <p>##So we stop using Rails?</p> <p>Nonsense. I cannot understand, that people are moving away from using Rails because they think, a so called “leader” is moving into a wrong directinon.</p> <p>First of all, you can definitely move to another framework. There is <a href="http://www.sinatrarb.com/">Sinatra</a> for more low level applications or <a href="http://www.padrinorb.com/">Padrino</a> as an alternative with yet a smaller scope of functionality compared to Rails. But before moving away, you should definitely review the requirements you have for your application and think about how you would implement them in the various frameworks. Furthermore don’t think in a “monolithic Rails Way”. Yes, there is a Rails Way - in a way. But there are still many ways to walk the Rails way. Find your’s.</p> <p>Here are some suggestions that might help finding the one:</p> <p><a href="https://www.youtube.com/watch?v=-54SDanDC00">Component-based Architectures in Ruby and Rails</a> <a href="http://pivotallabs.com/hexagonal-rails-and-the-ludicrous-terminal-application/">Hexagonal Rails and The Ludicrous Terminal Application</a></p> <p>##About Testing</p> <p>Oh man, this is a big thing. DHH is again the bad guy because he said “TDD is dead”.</p> <p>But wait. Did he really? In my opinion he didn’t.</p> <p>There is a great disucssion going on between Martin Fowler, Kent Beck and David Heinemeier Hansson. Naturally, Martin and Kent have the position that TDD is a great thing and David is moving a way for reasons he is explaining. As of this writing, the first two parts out of five have been on air:</p> <p><a href="https://www.youtube.com/watch?v=z9quxZsLcfo">Is TDD dead?</a> <a href="https://www.youtube.com/watch?v=JoTB2mcjU7w">Is TDD dead? Part II</a></p> <p>scheduled for May 20, 2014: <a href="https://www.youtube.com/watch?v=YNw4baDz6WA">Is TDD dead? Part III</a></p> <p>The first two parts are providing a lot of insights from both point of views. I really like to watch them. After having seen them, one should be able to decide wether TDD is a good or bad fit.</p> <p>One thing is really clear: you should write tests! But you may stumble upon stones on the way to achive this goal:</p> <ul> <li>knowledge about what to test</li> <li>knowledge about how to test (TDD with test first, test after)</li> <li>does every team member have the skills to test?</li> <li>which tools should one use?</li> </ul> <p>And here is a good quote from Kent Beck heard in the second part of the before mentioned conversation:</p> <p>“Difficult testing is a sign for poor design” <em>(Kent Beck)</em></p> <p>This does not only count for developing software with TDD but also for general development.</p> <p>If the software is strong coupled or models are not following the <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">single responsibility principle</a>, you will not only have hard times to test your software, but also run into problems when extending or refactoring your application.</p> <p>I recently started to develop a new Rails based application and we made the following desicsions how to test:</p> <ul> <li>we don’t test controllers explicitely</li> <li>we are testing the public interface of models with <a href="http://rspec.info/">rspec</a></li> <li>we are testing the website by using <a href="https://github.com/jnicklas/capybara">Capybara</a></li> <li>we are free to test other parts of the application if needed</li> <li>we test JavaScript (Jasmyn or Mocha)</li> </ul> <p>So I expect you to ask, why not TDD. The answer is simple: because we don’t know how to do it <em>(feeling big storm of “whaaaaaatttt?” over my head)</em>.</p> <p>Another answer is, that I think we don’t need it - when using Rails. I personally compare Rails as a blank form where I have to fill in the missing parts in the inputfields. That means, Rails is providing a lot of (already tested) functinality I can use.</p> <p>For example in a controller. If used correctly, one will call a public method from a model to receive data from a database or execute some business logic. Now look again to the list. This is what I test because if this fails, I expect to have a big problem in my application.</p> <p>Hopefully I was able ot make clear, that the before mentioned statements count with respect to using Rails. When creating a plain Ruby application (or also a gem), this approach has to be changed to a wider testing model. But I am not sure if it has be TDD though and the leadership his taking (although he doesn’t).</p> <p>##Summary</p> <p>Some people in the Ruby community see a split between Rails and Ruby and proclaim two communities. Some people dislike DHH for his controversial discussion about TDD.</p> <p>I think a good, respectful, friendly and open discussion will help all “parts” in the Ruby world. Finally, the most important facts are:</p> <ul> <li>Rails is a great framework - when it fits the job: use it!</li> <li>DHH has a strong position about TDD and how software should be built. Share it or point your position out to discuss it</li> <li>stop blaming people for their position</li> <li>the Rails and Ruby community is not split</li> </ul> <p>And yes … DHH should stop using the F-word</p> <p>Happy coding!</p> http://andywenk.github.io/rails/2014/05/20/why-is-the-ruby-community-jog-around http://andywenk.github.io/rails/2014/05/20/why-is-the-ruby-community-jog-around 2014-05-20T00:00:00+00:00 We should support the OpenSSL project <p>We are all aware of the <a href="http://heartbleed.com/">Heartbleed Bug</a>. We all have changed our passwords. If not, stop reading and do it now!</p> <p>Nearly every sysadmin worldwide has done nothing else than updating her systems after the vulnerability was released. We know that a German contributor of the OpenSSL project has caused the bug two years ago.</p> <p>Now we are safe again. Let’s go back to work. Really? No! We are not and we should think a bit about why it happened.</p> <p>##The OpenSSL project</p> <p>The <a href="">OpenSSL project</a> is an Open Source project represented by the <a href="http://opensslfoundation.com/">OpenSSL Software Foundation, Inc.</a> and licensed under a <a href="http://www.openssl.org/source/license.html">Apache like license</a>. The main purpose of the project is to develop the SSL v2/v3 and TLS v1 protocols. These protocols are the defacto standard for cryptographic and secure transport of data in world wide used software. We use it on a daily basis - even though many of us are not aware about this fact.</p> <p>The project is very small. There is a five member core team and a eleven member development team.</p> <p>There are different ways <a href="http://www.openssl.org/support/">supporting the project</a> (taken form the project’s website):</p> <ul> <li> <p><strong>Join</strong> the online community Participate in the online community of developers, testers, and contributing end users working to make OpenSSL a better product.</p> </li> <li> <p><strong>Donate</strong> to the OpenSSL project Your donation will help add new capabilities to OpenSSL. Significant sponsors have a say in the future direction of OpenSSL as well as acknowledgements and logo placements.</p> </li> <li> <p><strong>Fund</strong> the OpenSSL project via a support contract Obtain the protection of formal support contract coverage for your commercial or government enterprise and support ongoing OpenSSL development.</p> </li> <li> <p><strong>Hire</strong> individual OpenSSL team members Some OpenSSL team members are available for custom consultancy contract work.</p> </li> </ul> <p>##The OpenSSL shitstorm</p> <p>After the release of the Heartbleed vulnerabilty many articles have been written about it. Various <em>insider</em> have questioned the Open Source idea and have started to complain about the possibility, that such a bug can happen at all. You are all wrong!</p> <p>The bug was an oversight that should not happen. Thats not questionable at all. But how many companies using OpenSSL have checked the <a href="http://www.openssl.org/source/">Open Source code</a> before making a lot of money with services strongly relying on OpenSSL? Why did they not find the bug when it is such an easy bug? Because they believe in Open Source and that is a good thing. They should not complain about it in any way. They should start to support the project!</p> <p>##Looking at an Open Source project</p> <p>The power of an Open Source project is its community. You can use, integrate or modify the produced source code or software at your needs. That’s what the project is giving to you. The project is taking care of the development with it’s core developers and integrates patches provided by contributors. It is also taking care of bugs or security issues. But the project is giving no warranty:</p> <blockquote> <p>Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</p> </blockquote> <p>The snipped is taken from the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2 License</a>.</p> <p>Does this mean, that the software is shitty? No - not at all. But the people contributing to the project are volunteers. A volunteer cannot be made responsible for what the project is doing in whole.</p> <p>The positive aspects are obvious. Many people have many different skills and experience. The community is discussing where the software is leading to. Plus point: it is not marketing driven. Throw that into a bucket and you will have a very good product.</p> <p>##The problem</p> <p>So far, we understood that an Open Source project relies on its community. The problem is the following sentence:</p> <blockquote> <p>It’s done when it’s done!</p> </blockquote> <p>This sentence has two implications:</p> <ul> <li> <p>the pace of the progress made is driven by the community. The more time contributors invest, the higher the pace is.</p> </li> <li> <p>if the community is small, the progress relies on few people. This can cause pressure or lack of reviewing code.</p> </li> </ul> <p>And here we come to to problem why such a simple bug in OpenSSL was not found: the code review was made by one person who did not see it.</p> <p>In the <a href="http://couchdb.apache.org">CouchDB project</a>, we have the rule, that a patch (git pull request) has to be acknowledged (+1) by two different committers. But what to do if there are not enough committers or reviewers? The answer is simple: if we want high quality Open Source software, we have to support the project in various ways. This can be done with manpower and also financially.</p> <p>##Support the OpenSSL project</p> <p>I have said this before and will repeat myself again: support the projects you benefit from! Steve Marquess, co-founder, president and business manager of the <a href="http://opensslfoundation.com/who.html">OpenSSL Software Foundation, Inc.</a> has written a <a href="http://veridicalsystems.com/blog/of-money-responsibility-and-pride/">emotional blog post</a> you should read now. Just take the numbers. The donations are like nothing.</p> <p>Again: we are using SSL on a daily basis so we have the responsibility to support the OpenSSL project. If we don’t, we do not have the right to complain about our stolen passwords. We have to accept the fact, that bugs can cause huge problems!</p> <p>###Disclaimer</p> <p>This is my personal opinion. I am wether writing as a member of the Apache CouchDB PMC, nor does this writing reflect the opinion of the Apache CouchDB PMC.</p> <p>I have also heard about controversial discussions about the OpenSSL Software Foundation Inc. but have not read related articles yet. If you find one or wrote one, please get in touch with me (andy@nms.de). Though it will not change my opinion about the need of supporting Open Source projects we benefit from.</p> http://andywenk.github.io/security/2014/04/20/we-should-support-the-openssl-project http://andywenk.github.io/security/2014/04/20/we-should-support-the-openssl-project 2014-04-20T00:00:00+00:00 Running local vm's with Packer, Bento and Vagrant <p>Inspired by <a href="https://twitter.com/rnewson">Bob Newson</a> while following the CouchDB <a href="freenode.net#couchdb-dev">dev IRC chat</a>, I gave <a href="http://www.packer.io/">Packer</a> and <a href="https://github.com/opscode/bento">Bento</a> a try. The idea is to build <a href="http://www.vagrantup.com/">Vagrant</a> boxes or use existing ones and start them locally for testing purposes. In this article I will show how to get a Centos 6.5 box running.</p> <p>Packer is supporting many different <em>Builders</em> like VirtualBox, VMware, and Amazon EC2. We will use VirtualBox in this article. If you are not using it already, please <a href="https://www.virtualbox.org/wiki/Downloads">download</a> it. The usage is free of charge.</p> <p>##Install Packer</p> <p>This step is easy. The packer project is providing various <a href="http://www.packer.io/downloads.html">installer</a> for the most important platforms (Mac OS X, Linux, Windows, FreeBSD, OPenBSD). As we are using Mac OS X, we download and installed it. Easy!</p> <p>##Clone the Bento repository</p> <p>The Bento project is providing <em>Templates</em> for creating machine images. To be able to use these templates, the easiest way is to clone the Bento repository. Before that, we create a directory where all the vms will live.</p> <div class="highlighter-rouge"><pre class="highlight"><code>~: mkdir vm &amp;&amp; cd vm ~/vm: git clone https://github.com/opscode/bento.git </code></pre> </div> <p>The repository will be cloned into the directory <em>~/vm/bento</em>. Within the Bento repository, you will also find pre-built <em>Base-Boxes</em> you can download and use with Vagrant.</p> <p><strong>side note:</strong> I really like, that the Packer project has defined and written down the <a href="http://www.packer.io/docs/basics/terminology.html">terminology</a> they are using. This helps a lot while speaking about Packer, because everybody is using the same wording. You should definitely read the page above.</p> <p>##Building a box</p> <p>Now it’s time to create our first box. The Packer API is very intuitive. For a deeper insight, you should read the <a href="http://www.packer.io/docs/">documentation</a>. The following steps will show, how to create a CentOS 6.5 box. We will then start the box with Vagrant later.</p> <p>First, we create a target directory:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm: mkdir centos-6.5 </code></pre> </div> <p>Now we start creating the box. This will take a while so we should be patient:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm: cd bento/packer ~/vm/bento/packer: packer build -only=virtualbox-iso ../../centos-6.5/centos-6.5-x86_64.json </code></pre> </div> <p>When the creation process is finished and no errors occured, we will find the created machine image in the following directory:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm/bento/builds/virtualbox: opscode_centos-6.5_chef-provisionerless.box </code></pre> </div> <p>In the final step, we will move the created image to our before created directory:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm/bento/builds/virtualbox: mv opscode_centos-6.5_chef-provisionerless.box ~/vm/centos-6.5/ </code></pre> </div> <p>As already mentioned, we could have downloaded the image also from the bento repository page:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm/bento/builds/virtualbox: cd ~/vm/centos-6.5 ~/vm/centos-6.5: wget http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box </code></pre> </div> <p>##Installing Vagrant</p> <p>We will need to install Vagrant to be able to run the image we created in the previous step. The Vagrant project is providing binary packages for Mac OS X, Windows, Debian, Ubuntu, CentOS, Redhat and Fedora. So let’s download the Mac OS X binary:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm/centos-6.5: cd ~/Downloads ~/Downloads: wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.5.3.dmg </code></pre> </div> <p>Then we install the package with the usual procedure on Mac OS X.</p> <p>##Running the machine image with Vagrant</p> <p>This is the final step where we create the machine image. Let’s first move again to the directory, where our <em>box</em> lives.</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/Downloads: cd ~/vm/centos-6.5 </code></pre> </div> <p>Now we add our box to Vagrant. It is required to set a name and the path to our box. This is just one option out of three. Please refer to the <a href="https://docs.vagrantup.com/v2/cli/box.html">Vagrant documentation</a> to see the other options. This will also enable us to start the box by name later:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm/centos-6.5: vagrant box add --name centos-6.5 opscode_centos-6.5_chef-provisionerless.box ==&gt; box: Adding box 'centos-6.5' (v0) for provider: box: Downloading: file:///Users/andwen/vm/centos-6.5/opscode_freebsd-10.0_chef-provisionerless.box ==&gt; box: Successfully added box 'centos-6.5' (v0) for 'virtualbox'! </code></pre> </div> <p>And now we have to initialize the box:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm/centos-6.5: vagrant init centos-6.5 opscode_centos-6.5_chef-provisionerless.box A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on `vagrantup.com` for more information on using Vagrant. </code></pre> </div> <p>When we look at the directorys content, we see the created Vagrantfile. This file includes all the neccessary information to start the virtual machine. We do this by running the following command:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm/centos-6.5: vagrant up vagrant up Bringing machine 'default' up with 'virtualbox' provider... ==&gt; default: Importing base box 'centos-6.5'... ==&gt; default: Matching MAC address for NAT networking... ==&gt; default: Setting the name of the VM: centos-65_default_1397870052419_92480 ==&gt; default: Fixed port collision for 22 =&gt; 2222. Now on port 2200. ==&gt; default: Clearing any previously set network interfaces... ==&gt; default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==&gt; default: Forwarding ports... default: 22 =&gt; 2200 (adapter 1) ==&gt; default: Booting VM... ==&gt; default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2200 default: SSH username: vagrant default: SSH auth method: private key default: Warning: Connection timeout. Retrying... ==&gt; default: Machine booted and ready! ==&gt; default: Checking for guest additions in VM... ==&gt; default: Mounting shared folders... default: /vagrant =&gt; /Users/andwen/Documents/vm/centos-6.5 </code></pre> </div> <p>Now, the virtual machine has started. We can now connect to it via ssh. The user is <em>vagrant</em> and the password is <em>vagrant</em> as well. The ssh port was set to <em>2200</em>:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm/centos-6.5: ssh -p 2200 vagrant@127.0.0.1 The authenticity of host '[127.0.0.1]:2200 ([127.0.0.1]:2200)' can't be established. RSA key fingerprint is 64:60:5d:ba:02:61:01:09:a4:9a:55:95:88:43:14:0a. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[127.0.0.1]:2200' (RSA) to the list of known hosts. vagrant@127.0.0.1's password: Last login: Fri Apr 18 22:26:30 2014 from 10.0.2.2 [vagrant@localhost ~]$ </code></pre> </div> <p>Welcome to your first virtual machine setup with Packer, Bento and Vagrant.</p> <p>##Removing the box</p> <p>Because all the above is very easy, we will likely use this method to create virtual machines quite often. This will result in many machines and we will have the need to remove boxes. This is quite simple. First we will check which boxes exist:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm/centos-6.5: vagrant box list centos-6.5 (virtualbox, 0) centos-6.5-2 (virtualbox, 0) </code></pre> </div> <p>So let’s remove the box centos-6.5-2:</p> <div class="highlighter-rouge"><pre class="highlight"><code>~/vm/centos-6.5: vagrant box remove centos-6.5-2 Removing box 'centos-6.5-2' (v0) with provider 'virtualbox'... </code></pre> </div> <p>##Summary</p> <p>Packer, Bento and Vagrant are really great tools to set up virtual machines. In this article, we discussed how to do this based on VirtualBox. I start to use this to test CouchDB releases. There is still some work to do on the machine to get CouchBD installed, but it is definitely less time consuming compared to running various machines with the most important OS.</p> http://andywenk.github.io/server/2014/04/19/running-local-vms-with-bento-and-vagrant http://andywenk.github.io/server/2014/04/19/running-local-vms-with-bento-and-vagrant 2014-04-19T00:00:00+00:00 Use SPDY with Nginx and Passenger for Rails <p>I am using <a href="https://www.phusionpassenger.com/">Passenger</a> with <a href="http://nginx.org/">Nginx</a> to serve Rails applications. Although I was thinking about moving to <a href="http://puma.io/">Puma</a> because of some technical reasons, I still think that Passenger is a solid, prooved and good webserver for Rails applications.</p> <p>As you already know, we are waiting for <a href="http://http2.github.io/">HTTP/2</a> and <a href="http://en.wikipedia.org/wiki/SPDY">SPDY</a>. SPDY is basically the same as HTTP but does always include TLS encryption and is able to use multiplexing (plus other cool features). This means parallel transfer of assets because only one connection per client is required. Woot!</p> <p>Passenger does not include SPDY from scratch but Phusion is providing a patched binary you can integrate. As of this writing, the binary does support SPDY/2. Here is a list how to integrate the binary. I assume you have compiled Nginx with Passenger. Please do read first the whole list and start the work afterwards.</p> <p>##1. Follow the guide</p> <p>Hongli Lai (<a href="https:/twitter.com/honglilai">@honglilai</a>) has written a guide, how to use Nginx and SPDY. Read the steps here: <a href="http://blog.phusion.nl/2013/08/21/use-nginx-spdy-without-compiling-nginx-and-without-a-recent-openssl/">Use Nginx + SPDY, without compiling Nginx and without a recent OpenSSL</a> but do not start immediately.</p> <p>I am not sure why the title has “without a recent OpenSSL” because you will see later, that the tests for the Heartbleed bug do pass.</p> <p>##2. Follow these steps</p> <p>We do have a working Nginx installation already, so there is no need to install Nginx (as stated in the guide). What we need is the patched binary and replace the existing one. I have asked Hongli in the comments below the post about why there is no nginx tar anymore. It is just renamed. Hongli has upgraded the blog post thankfully. Here is what you need to do:</p> <h4 id="a-add-the-deb-source-from-phusion-to-your-sourceslist">a. Add the deb source from Phusion to your sources.list.</h4> <p>On Ubuntu, simply add a file in the <em>sources.list.d</em> directory</p> <div class="highlighter-rouge"><pre class="highlight"><code>touch /etc/apt/sources.list.d/passenger.list </code></pre> </div> <p>and add this content:</p> <div class="highlighter-rouge"><pre class="highlight"><code>deb https://oss-binaries.phusionpassenger.com/apt/passenger precise main </code></pre> </div> <p>####b. Upgrade your system</p> <div class="highlighter-rouge"><pre class="highlight"><code>sudo apt-get update sudo apt-get upgrade </code></pre> </div> <p>You MAY receive ERRORS. Don’t worry and keep on going.</p> <p>####c. Download the binary</p> <p>As of this writing it is the source below. It may be different when you read this post. You can simply check <a href="https://oss-binaries.phusionpassenger.com/binaries/passenger/by_release">https://oss-binaries.phusionpassenger.com/binaries/passenger/by_release</a>. It is VERY important, that the binaries version is the exact same version as of your Nginx installation.</p> <div class="highlighter-rouge"><pre class="highlight"><code>curl -O https://oss-binaries.phusionpassenger.com/binaries/passenger/by_release/4.0.41/webhelper-1.4.7-x86_64-linux.tar.gz curl -O https://oss-binaries.phusionpassenger.com/binaries/passenger/by_release/4.0.41/webhelper-1.4.7-x86_64-linux.tar.gz.asc </code></pre> </div> <p>####d. Get the developers gpg key and verify the tar archive</p> <div class="highlighter-rouge"><pre class="highlight"><code>gpg --recv-keys AC40B2F7 gpg --verify webhelper-1.4.7-x86_64-linux.tar.gz.asc </code></pre> </div> <p>No errors should show up.</p> <p>####e. Extract the archive and rename the binary to nginx</p> <p>As written in the guide by Hongli, Phusion renamed the binary to PassengerWebHelper. Simply rename it to <em>nginx</em>.</p> <div class="highlighter-rouge"><pre class="highlight"><code>tar xzvf webhelper-1.4.7-x86_64-linux.tar.gz mv PassengerWebHelper nginx </code></pre> </div> <p>####f. Copy the binary to the correct place. It may be different in your system depending on where you have installed Nginx</p> <div class="highlighter-rouge"><pre class="highlight"><code>sudo cp /usr/sbin/nginx nginx.original sudo /etc/init.d/nginx stop sudo cp nginx /usr/sbin/ </code></pre> </div> <p>####g. Update your Nginx vhost configuration.</p> <p>For the regarding SSL domain, yop need to add the keyword <em>spdy</em> to the <em>listen</em> directive:</p> <div class="highlighter-rouge"><pre class="highlight"><code>listen 443 default_server ssl spdy deferred; </code></pre> </div> <p>####h. Restart nginx</p> <div class="highlighter-rouge"><pre class="highlight"><code>sudo /etc/init.d/nginx restart </code></pre> </div> <p>####i. Check if SPDY is activated</p> <div class="highlighter-rouge"><pre class="highlight"><code>http://spdycheck.org/#www.YOUR_DOMAIN.com </code></pre> </div> <p>####j. Check that the doamin is not vulnerable agints the Heartbleed bug</p> <div class="highlighter-rouge"><pre class="highlight"><code>http://filippo.io/Heartbleed/#www.YOUR_DOMAIN.com </code></pre> </div> <p>If everything works, you should now have SPDY support for your Rails application. Go and check out the parallel transfer of the sources in your browsers developer toolbar and enjoy :-)</p> http://andywenk.github.io/server/2014/04/10/use-spdy-with-nginx-and-passenger-for-rails http://andywenk.github.io/server/2014/04/10/use-spdy-with-nginx-and-passenger-for-rails 2014-04-10T00:00:00+00:00 CouchDB 1.5.1 has been released please promote <h2 id="promote-the-couchdb-151-release">Promote the CouchDB 1.5.1 release</h2> <p>(this is proudly stolen from the CouchDB mailinglist)</p> <p>Being a volunteer organisation, we rely on you to help us promote releases.</p> <p>Here is the official blog post:</p> <p><a href="https://blogs.apache.org/couchdb/entry/apache_couchdb_1_5_1">https://blogs.apache.org/couchdb/entry/apache_couchdb_1_5_1</a></p> <p>Here is the official tweet:</p> <p><a href="https://twitter.com/CouchDB/status/453941428675411968">https://twitter.com/CouchDB/status/453941428675411968</a></p> <p>And Google+ post:</p> <p><a href="https://plus.google.com/109226482722655790973/posts/J7YFWF5Z32T">https://plus.google.com/109226482722655790973/posts/J7YFWF5Z32T</a></p> <p>We also have a Hacker News item:</p> <p><a href="https://news.ycombinator.com/item?id=7560612">https://news.ycombinator.com/item?id=7560612</a></p> <p>And several Reddit items:</p> <p><a href="http://www.reddit.com/r/programming/comments/22mcl3/apache_couchdb_151_released_security_release/">www.reddit.com/…/apache_couchdb_151_released_security_release/</a> <a href="http://www.reddit.com/r/programming/comments/22mcl3/apache_couchdb_151_released_security_release/">www.reddit.com/…/apache_couchdb_151_released_security_release/</a> <a href="http://www.reddit.com/r/nosql/comments/22mcrm/apache_couchdb_151_released_security_release/">www.reddit.com/…/apache_couchdb_151_released_security_release/</a> <a href="http://www.reddit.com/r/Database/comments/22mcu3/apache_couchdb_151_released_security_release/">www.reddit.com/…/apache_couchdb_151_released_security_release/</a></p> <p>Please take a moment to share these links with your friends.</p> <p>Retweet us if you use Twitter, and upvote us if you use Google+, Hacker News, or Reddit.</p> <p>(Note that Hacker News users may want to navigate to the item from the front page. I believe up votes are not counted when you link to an item directly.)</p> <p>If you like, you could monitor these threads and respond to people with questions. This is a great opportunity for community outreach.</p> <p>If you have any other promotion you’d like to highlight, please reply to this thread.</p> http://andywenk.github.io/couchdb/2014/04/10/couchdb-151-has-been-released-please-promote http://andywenk.github.io/couchdb/2014/04/10/couchdb-151-has-been-released---please-promote 2014-04-10T00:00:00+00:00 The CouchDB community is second to none <p>Moin Moin,</p> <p>Jan Lehnardt sent a link to the CouchDB <a href="http://couchdb.apache.org/#marketing-mailing-list">marketing@couchdb.apache.org</a> mailing list where <a href="https://twitter.com/stickbyatlas">Ari Najarian</a> used CouchDB in a <a href="http://www.torusoft.com/blog/5-days-of-code-curriculum-day-3">five part course to teach beginners how to program</a>. It’s a great read and I invite you to visit the page.</p> <p>I would like to slice out one quote from the article where Ari described the CouchDB community:</p> <p><em>“The personalities and voices in the CouchDB community are, hands down, the most helpful, generous, welcoming, insightful, ethical, principled, future-minded group of developers I’ve ever encountered in one place. As far as online communities go, you can’t find a safer, more encouraging group of advocates. These people are role models that will help beginners to understand what “open-source” can really be about: social justice, diversity, inclusion, and collaboration.”</em></p> <p>This is the reason why I became a part of the Apache CouchDB project - because the community is so awesome.</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/couchdb/2014/03/11/the-couchdb-community-is-second-to-none http://andywenk.github.io/couchdb/2014/03/11/the-couchdb-community-is-second-to-none 2014-03-11T00:00:00+00:00 launchrocket with homebrew cask <p>I just stumbled upon a tweet from <a href="https://twitter.com/ThorstenRinne" target="_blank">https://twitter.com/ThorstenRinne</a> retweeted by <a href="https://twitter.com/tobmaster" target="_blank">https://twitter.com/tobmaster</a> where Thorsten pointed us to <a href="https://github.com/jimbojsb/launchrocket." target="_blank">https://github.com/jimbojsb/launchrocket.</a> It is a</p> <p><em>Mac PreferencePane for managing services with launchd/launchctl</em></p> <p>One option to install launchrocket is to install it via <a href="https://github.com/phinze/homebrew-cask" target="_blank">homebrew-cask</a>. I did not know this tool. It is a nice tool to install binary Mac Applications:</p> <p><em>Homebrew-cask provides a friendly homebrew-style CLI workflow for the administration of Mac applications distributed as binaries.</em></p> <p>So I thought let me try this. The way to get it done is dead simple. First install homebrew-cask:</p> <pre><code>brew tap phinze/cask brew install brew-cask </code></pre> <p>Easy. Now install launchrocket:</p> <pre><code>brew tap jimbojsb/launchrocket brew cask install launchrocket </code></pre> <p>You will be asked to give your sudo password once for all preceding installations when these privileges are neede:</p> <pre><code>==&gt; We need to make Caskroom for the first time at /opt/homebrew- cask/Caskroom ==&gt; We'll set permissions properly so we won't need sudo in the future Password: </code></pre> <p>That was easy also. No open the <em>System Preferences</em> and find launchrocket</p> <p><img src="https://31.media.tumblr.com/9b3c80f28979316c6dba8cb4fef50350/tumblr_inline_n0ovu7KtxX1qa0m1w.png" alt=""/></p> <p>Open it with a click and see a very nice GUI for all the services you can start easily from here:</p> <p><img src="https://31.media.tumblr.com/b7c32fbc13c8d313564b5ea5a1932ae6/tumblr_inline_n0ovw7h4lj1qa0m1w.png" alt=""/></p> <p>Really cool. I like that a lot and maybe you find that useful also :)</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/server/2014/02/08/launchrocket-with-homebrew-cask http://andywenk.github.io/server/2014/02/08/launchrocket-with-homebrew-cask 2014-02-08T18:13:05+00:00 Rack - the underlying machine of Ruby web applications <p>Moin Moin,</p> <p>I you have ever wondered how a Ruby web applications/frameworks like Rails, Sinatra or Padrino work, you should understand what Rack is doing.</p> <p>Rack was created 2007 by Christian Neukirchen (<a href="http://chneukirchen.org/blog/archive/2007/02/introducing-rack.html" target="_blank">inital blog post</a>). Rack does this:</p> <p><em>"Rack aims to provide a minimal API for connecting web servers and web frameworks."</em></p> <p>Pratik Naik wrote a nice thread with some <a href="http://m.onkey.org/ruby-on-rack-1-hello-rack" target="_blank">basic examples</a>. You should read it.</p> <p>Actually I had problems installing Mongrel so I simply changed to <em>Thin</em> and used a <em>Gemfile</em> and an <em>.rvmrc</em> file for convenience. I put the code together in a mini project called airforec_one. Please note the typo in the name :).</p> <p><strong>.rvmrc</strong></p> <pre><code>rvm use ruby-2.0.0-p353@airforec_one --create </code></pre> <p><strong>Gemfile</strong></p> <pre><code>source "https://rubygems.org" gem 'rack' gem 'thin' </code></pre> <p><strong>init.rb</strong></p> <pre><code>require 'rubygems' require 'rack' require 'thin' class HelloMrPresident def call(env) [200, {"Content-Type" =&gt; "text/html"}, "Hey this is the president. Whazz up?"] end end Rack::Handler::Thin.run HelloMrPresident.new, :Port =&gt; 3000 </code></pre> <p>Now run the code:</p> <pre><code>ruby init.rb Thin web server (v1.6.1 codename Death Proof) Maximum connections set to 1024 Listening on 0.0.0.0:3000, CTRL+C to stop </code></pre> <p>And open <a href="http://localhost:3000" target="_blank">http://localhost:3000</a></p> <p>What you see is the beginning of your career as a Ruby web framework developer. But just if Rails is too heavy, Sinatra is too less and Padrino is too young.</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/programming/2014/01/20/rack-the-underlying-machine-of-ruby-web-applications http://andywenk.github.io/programming/2014/01/20/rack-the-underlying-machine-of-ruby-web-applications 2014-01-20T23:40:37+00:00 What I am recently reading <h1>Moin Moin,</h1> <p>having over two weeks off - with Christmas during this time - means there is a good portion of time I can use to read. I really like reading a lot - unfortunately mostly textbooks. Actually, I started to force myself to also read some different stuff what leads to the first book I am reading.</p> <h2>Books</h2> <p><strong>Momo</strong></p> <p>When I was a kid and teeny, I hated reading. I think I read around ten books until I was eighteen. That resulted in very bad grades in school for German class. Today, as I am trained a little more, I find a lot of typos in novels and also textbooks &#8230; woot :-). But one book fascinated me and I just needed four days to read it: <em>Momo</em>, written by <em>Michale Ende</em>. I guess everybody knows this book. If not - go and get a copy! It is translated in many many languages.</p> <p><img src="https://31.media.tumblr.com/7aca8d28eb63a7e0ffb7b07fb5c28835/tumblr_inline_myvzjgbae61qa0m1w.jpg" alt=""/></p> <p><a href="http://www.amazon.de/Momo-Retro-Ausgabe-Michael-Ende/dp/3522201884/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1388856763&amp;sr=1-1&amp;keywords=momo" target="_blank">amazon link</a></p> <p><strong>Companion to the Papers of Donald Knuth</strong></p> <p>I am fascinated by Donald E. Knuth (DEK). Unfortunately I am not a mathematician (even though my interest is growing the older I get) and because of that, the theoretical stuff is really hard for me to understand. But I am still trying hard to read <em>The Art of Computer Programming</em> :-). I read <em>Companion to the Papers of Donald Knuth</em> already - I guess in three days. It consists mostly of conversations between DEK and Dikran Karaguezian. They speak about Knuth&#8217;s live and important things he thinks and did. It&#8217;s massively interesting.</p> <p><img src="https://31.media.tumblr.com/56c07e8d01af016ffbd1046a48b83d57/tumblr_inline_myvzusLnEG1qa0m1w.jpg" alt=""/></p> <p><a href="http://www.amazon.de/Companion-Papers-Donald-Knuth-Lecture/dp/157586634X/ref=sr_1_cc_1?s=aps&amp;ie=UTF8&amp;qid=1388856803&amp;sr=1-1-catcorr&amp;keywords=Companion+to+the+Papers+of+Donald+Knuth" target="_blank">amazon link</a></p> <p><strong>Selected Papers on Computer Science</strong></p> <p>Resulting in reading the previous book, I bought Selected Papers on Computer Science from DEK. In this book he is explaining many CS aspects to a broader audience with more or less no mathematical or programming background. I started just a little bit and am looking forward to reading it. DEK&#8217; writing style is really amazing and great.</p> <p><img src="https://31.media.tumblr.com/d8d0766edfaf4405526e114794f2e946/tumblr_inline_myw06hyy5u1qa0m1w.jpg" alt=""/></p> <p><a href="http://www.amazon.de/gp/product/1881526917/ref=oh_details_o00_s00_i00?ie=UTF8&amp;psc=1" target="_blank">amazon link</a></p> <p><strong>Notes of a Dirty Old Man - Charles Bukowski</strong></p> <p>Ah - here is the first non technical book of great value. I love Bukowski. He is doing <em>literature porn</em> at it&#8217;s best. The book includes 36 short stories or columns he has written for a newspaper. You can&#8217;t imagine how fucked up and dirty this drinking guy is. It&#8217;s really funny and amusing to read.</p> <p><img src="https://31.media.tumblr.com/93d439c74317d56e1f73781f5d70b50d/tumblr_inline_myw0u0agUJ1qa0m1w.jpg" alt=""/></p> <p><a href="http://www.amazon.de/Aufzeichnungen-eines-Dirty-Old-Man/dp/359690515X/ref=sr_1_cc_1?s=aps&amp;ie=UTF8&amp;qid=1388856844&amp;sr=1-1-catcorr&amp;keywords=aufzeichnungen+eines+dirty+old+man" target="_blank">amazon link</a></p> <p><strong>The Annotated Turing</strong></p> <p>Everybody in the field of CS knows turing and knows the ACM and knows the Turing award. I stumbled about the book <em>The Annotated Turing</em> written by Charles Petzold (a Microsoft textbook author) while searching on amazon after Turing. I strongly recommend this book to everyone who wants to understand what a Turing machine is and how it describes a lot the basics for modern computers. The author annotates the whole paper <em>ON COMPUTABLE NUMBERS, WITH AN APPLICATION TO THE ENTSCHEIDUNGSPROBLEM</em> and explains what Turing meant. Petzold is giving a lot of examples of Touring machines and as an introduction some historical background to mathematics.</p> <p><img src="https://31.media.tumblr.com/af2d0dec77f4b31a542e4bd01f47993f/tumblr_inline_myw19eHrcJ1qa0m1w.jpg" alt=""/></p> <p><a href="http://www.amazon.de/gp/product/0470229055/ref=oh_details_o00_s00_i01?ie=UTF8&amp;psc=1" target="_blank">amazon link</a></p> <p><strong>Doctor Sleep - Steven King</strong></p> <p>In the range of the ten books I read when I was a teen are also some Steven King books. And for sure did I see <em>Shining</em> not only once. So there was <em>Doctor Sleep</em> under the Christmas Tree - really fitting :-). It&#8217;s quite a long book with 704 pages (German edition) so I need to prepare myself to find the mood to read it. The last book in the same size I started reading &#8230; erm &#8230; one and a half years ago :-) &#8230;</p> <p><img src="https://31.media.tumblr.com/f783cd5ea43fe2ebe07fb49287545ef0/tumblr_inline_myw36jfjVy1qa0m1w.jpg" alt=""/></p> <p><a href="http://www.amazon.de/Doctor-Sleep-Roman-Stephen-King/dp/3453268555/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1388859897&amp;sr=1-1&amp;keywords=doctor+sleep" target="_blank">amazon link</a></p> <h2>Recap</h2> <p>Hopefully this short list is inspiring to someone or at least informative. There are quite some other books beside my bed or laying around in some preferred reading corners in our house but the list above is what I am concentrating on at the moment.</p> <p>After having read many textbooks, it is becoming harder and harder to find good ones. All O&#8217;Reilly books and also Galileo Computing books (including both my books) suffer from the dictated form they have to have. I know that the authors have just little influence to this fact but it still makes them kind of boring (not including my books :-) ). Have you read one, you have read all of them beside the changed topic. The books from DEK for example are different because he is dictating the form.</p> <p>My intention is not to blame any of the authors of O&#8217;Reilly or Galileo Computing books but there is a difference between textbooks and textbooks and I start to recognise that a lot. Therefor I ask the distributors to let authors write higher quality books. You should find some way&#8217;s how to do that.</p> <p><strong>EDIT:</strong> If you are interested in mathematical books check out <a href="http://wp.kjro.se/2013/12/27/5-insanely-great-books-about-mathematics-you-should-read" target="_blank">the list in the blogpost &#8220;5 insanely great books about mathematics you should read&#8221; by kjrose</a>.</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/reading/2014/01/04/what-i-am-recently-reading http://andywenk.github.io/reading/2014/01/04/what-i-am-recently-reading 2014-01-04T20:18:00+00:00 Last day at SinnerSchrader <p>Moin Moin,</p> <p>well - after nearly four years I am leaving SinnerSchrader. Up from January 2014 I will join <a href="http://www.sumcumo.com/" target="_blank">http://www.sumcumo.com/</a> and I am looking forward to new challenges.</p> <p>SinnerSchrader is awesome. I really liked to work there. But what was really awesome was my team there. I guess it was the best team I worked with. And that is a fact and what I will missing. Not to say, that the new team will not be awesome but that&#8217;s something I have to learn first :) (funny thing: there is Sven and Enrico I already worked with at SinnerSchrader :) ).</p> <p>I will not annoy you with details about our work for our customer Unitymedia. Just the fact, that when I started to work for them, it was one of the smaller customers at SinnerSchrader and Unitymedia will rise to be No1 next year or so. But what is so damn awesome, is the fact, that we were always able to do the job and did not loose our friendship while doing so. The team was nearly perfect.</p> <p>At Friday, December 20th I invited to drink some beers in our cafeteria. They made a present for me. Just look:</p> <p><img src="https://31.media.tumblr.com/aa52fce712c0f37ab94081a96b5a19c4/tumblr_inline_my9rlq1G691qa0m1w.jpg" alt=""/></p> <p>30 bottels of beer from over the world and a super nice and big card with cool team photos and good wishes. I guess they know one of my hobbies :). Thank you so much&#160;!!!</p> <p>I just want to say thank you Laura, Sarah, Melina, Jan, Peter and also to the newer team mates Iris, Darinka, Tobi, Hendrik, Tim and Bastian. You fuckin&#8217; rock. Thanks for everything!!!</p> <p>This is not the end &#8230; this is just a new beginning and we will see us again :)</p> <p>Love</p> <p>Andy</p> http://andywenk.github.io/work/2013/12/23/last-day-at-sinnerschrader http://andywenk.github.io/work/2013/12/23/last-day-at-sinnerschrader 2013-12-23T17:16:20+00:00 Invitation to become a CouchDB committer <p>Moin Moin,</p> <p>I am a fan and user of CouchDB since 2007. At this time CouchDB wasn&#8217;t an ASF project and Jan Lehnardt (<a href="https://twitter.com/janl" target="_blank">@janl</a>) took the mission to promote CouchDB. It was a good time because NoSQL databases started to emerge. Btw - CouchDB was publicly introduced in 2005 by it&#8217;s creator Damien Katz.</p> <p>Well coming from a relational world (<a href="http://www.pg-praxisbuch.de" target="_blank"><a href="http://www.pg-praxisbuch.de" target="_blank">http://www.pg-praxisbuch.de</a></a>) it took me some time to get the big picture. But after playing around with it (must have been 0.6 or so) I really started to like it a lot. At this time Benoit Chesneau (<a href="https://twitter.com/benoitc" target="_blank">@benoitc</a>) took over the fork for couchapp - complete web applications served solely by CouchDB. I took part in the discussion show that could work out.</p> <p>In late 2008 CouchDB became a Apache project.</p> <p>Well in 2011, Galileo Computing asked me if I would write a book about CouchDB. It was 1.1 and 1.2 was just next door. I decided to take the chance and asked awesome Till Klampaeckel (<a href="http://twitter.com/klimpong" target="_blank">@klimpong</a>) if he would write the book with me. Luckily he said yes and imho the book is really cool! Unfortunately the book did not run well in Germany so Galileo decided just some days ago to remove it (if you are interested in a copy ping me!).</p> <p>As I am not an Erlang expert yet I never really contributed to the project but had always the fan cap on my head. I was still in contact with Jan and after having met him and Till at JSConf 2013 in Berlin I asked what would be a good contribution. He said that the documentation should be translated. Bingo. I like writing and I like documentation and I like translating (a bit ;-) ). But what I like most is contributing in such a cool project. So around two months ago I started a post that I would like to integrate L10n into CouchDB. The feedback was really big. Well my proposals seemed to be good and a project like Apache CouchDB needs people to push the parts they want to contribute. So I was really overwhelmed when Noah Slater (<a href="http://twitter.com/nslater" target="_blank">@nslater</a>) and the core team invited me to become a CouchDB committer. Wow. That&#8217;s really awesome. I feel honoured and I am strongly motivated to do my best for CouchDB.</p> <p>Thanks to the CouchDB core committers and community for electing me.</p> <p>If you are interested in contributing to the integration of L10n into CouchDB or contributing in general please don&#8217;t wait to ping me at andywenk@apache.org.</p> <p>Here are some links for you:</p> <p><a href="http://couchdb.apache.org" target="_blank"><a href="http://couchdb.apache.org" target="_blank">http://couchdb.apache.org</a></a><br/><a href="http://docs.couchdb.org/en/latest" target="_blank"><a href="http://docs.couchdb.org/en/latest" target="_blank">http://docs.couchdb.org/en/latest</a></a><br/><a href="http://wiki.apache.org/couchdb" target="_blank"><a href="http://wiki.apache.org/couchdb" target="_blank">http://wiki.apache.org/couchdb</a></a><br/><a href="http://couchdb-buch.de/" target="_blank"><a href="http://couchdb-buch.de/" target="_blank">http://couchdb-buch.de/</a></a></p> <p>IRC: irc.freenode.com -&gt; #couchdb</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/couchdb/2013/11/07/invitation-to-become-a-couchdb-committer http://andywenk.github.io/couchdb/2013/11/07/invitation-to-become-a-couchdb-committer 2013-11-07T20:16:00+00:00 [revised] git tab-completion on Mac OS X <p>Moin Moin,</p> <p>when using the git tab completions, it is annoying to update your .bash_profile when upgrading git to a new version, Assuming you have installed git via brew, you can automatically detect the version number with a small regex. Just update the lines in your .bash_profile i showed in <a href="http://andywenk.tumblr.com/post/43643531926/git-tab-completion-on-mac-os-x-when-installed-via" target="_blank">http://andywenk.tumblr.com/post/43643531926/git-tab-completion-on-mac-os-x-when-installed-via</a> with this:</p> <script src="https://gist.github.com/andywenk/6473801.js"></script><p>have fun!</p> <p>Cheers</p> http://andywenk.github.io/server/2013/09/07/revised-git-tab-completion-on-mac-os-x http://andywenk.github.io/server/2013/09/07/revised-git-tab-completion-on-mac-os-x 2013-09-07T08:13:33+00:00 install different software-version with homebrew <p>Moin Moin,</p> <p>recently, I had to install <a href="https://code.google.com/p/wkhtmltopdf/" target="_blank">wkhtmltopdf</a> via <a href="http://mxcl.github.io/homebrew/" target="_blank">homebrew</a> to be able to use <a href="https://github.com/pdfkit/pdfkit" target="_blank">pdfkit</a>. Installing wkhtmltopdf with homebrew is as simple as typing</p> <script src="https://gist.github.com/andywenk/6049817.js"></script><p>Unfortunately, the recent version did not work. So I had to install an older version. The actual Version can be seen with:</p> <script src="https://gist.github.com/andywenk/6049832.js"></script><p>What you will do is checkout the git repository of wkhtmltopdf in a special version - the list is already showing, how you do that. Be sure to change the directory to /usr/local. The repositories live here. Then, there are three steps: Checkout the git repository in the correct version, unlink the installed version and install the old one:</p> <script src="https://gist.github.com/andywenk/6049848.js"></script><p>If you want to switch rto the new version, you can do this with:</p> <script src="https://gist.github.com/andywenk/6049860.js"></script><p>And that&#8217;s it!</p> <p>Cheers</p> http://andywenk.github.io/server/2013/07/21/install-different-software-version-with-homebrew http://andywenk.github.io/server/2013/07/21/install-different-software-version-with-homebrew 2013-07-21T20:34:22+00:00 My ~/.gitconfig <p>Moin Moin,</p> <p>when you&#8217;re using git as your scm, you will probably love it&#8217;s command line interface. I am using it on a daily basis &#8230; heavily. I know that there are some quite good GUI&#8217;s (like <a href="http://www.sourcetreeapp.com/" target="_blank">SourceTree</a>) but I never got really into them. So if you&#8217;re interested to make your git-life a little more comfortable, you can check out my (small) .gitconfig:</p> <script src="https://gist.github.com/andywenk/5700580.js" type="text/javascript"></script><p>There are three entries worth mentioning:</p> <ol><li><p>always use &#8220;git pull &#8212; rebase&#8221; to avoid unnecessary merge commits</p></li> <li><p>use &#8220;_conflictstyle = diff3&#8221; for an advanced diff while solving conflicts during merge or rebase. You will see three different parts: your changes, their changes and the merged common ancestors. This gives you full access to all changes and you can choose what has to be merged</p></li> <li><p>check out the awesome alias &#8220;lg&#8221;. Full power overview what&#8217;Äs going on in your repo. Credits go out to my fine colleague Thomas <a href="http://twitter.com/thereincarnator" target="_blank">@Thereincarnator</a>.</p></li> </ol><p>Cheers</p> http://andywenk.github.io/server/2013/06/03/my-gitconfig http://andywenk.github.io/server/2013/06/03/my-gitconfig 2013-06-03T19:29:00+00:00 My Music at Reverbnation <p><img style="visibility:hidden;width:0px;height:0px;" border="0" width="0" height="0" src="http://c.gigcount.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEzNjcxNzkyMDEzOTImcHQ9MTM2NzE3OTIxNjEyNCZwPTI3MDgxJmQ9YmFubmVyX2ZpcnN*X2dlbiZnPTEmbz*wZWIx/OTE2MzA5ZTc*MTU2YmIwMGYzYWQ4MmE5MTk3ZCZvZj*w.gif"/><a href="http://www.reverbnation.com/c./a4/10116279/3319912/Artist/3319912/Artist/link" target="_blank"><img alt="Andy%20Wenk" border="0" src="http://www.reverbnation.com/c./a3/10116279/3319912/Artist/3319912/Artist/res.gif"/></a></p> http://andywenk.github.io/music/2013/04/28/my-music-at-reverbnation http://andywenk.github.io/music/2013/04/28/my-music-at-reverbnation 2013-04-28T20:00:53+00:00 Hiring: Are u a cool Rails Developer? We are looking for you! <p>Moin Moin,</p> <p>actually we are looking for a Rails Developer to extend our team. As you can imagine, we are nice boyz&#8217;n girlz and are looking for you. Check out the SinnerSchrader career site here:</p> <p><a href="http://www.sinnerschrader.com/jobs/softwareentwickler-ruby-on-rails-mw/" target="_blank">http://www.sinnerschrader.com/jobs/softwareentwickler-ruby-on-rails-mw/</a></p> <p><img src="http://media.tumblr.com/b4d0edc77ab9e08c4751a6ce763a5523/tumblr_inline_mlg54gNkmI1qz4rgp.png" alt=""/></p> <p>If you have any questions don&#8217;t hesitate to get in touch with me &#8230;</p> <p>Cheers</p> http://andywenk.github.io/work/2013/04/18/hiring-are-u-a-cool-rails-developer-we-are-looking http://andywenk.github.io/work/2013/04/18/hiring-are-u-a-cool-rails-developer-we-are-looking 2013-04-18T10:29:00+00:00 Installing CouchDB with Erlang R16B is broken - here is a fix <p>Moin Moin,</p> <p>I am using homebrew to install all needed software on my Mac (if available). When upgrading homebrew with</p> <script src="https://gist.github.com/andywenk/5344191.js" type="text/javascript"></script><p>you will get the newest Erlang R16B. This is not compatible witrh CouchDB 1.2.1. You have to switch back to Erlang R15B in a specific version. Simply using brew install erlang-15 will not work!</p> <p>Here is the workaround:</p> <script src="https://gist.github.com/andywenk/5344201.js" type="text/javascript"></script><p>This is taken from an issue <a href="https://github.com/mxcl/homebrew/issues/18256" target="_blank">here</a>. The important post is from Jan <a href="https://github.com/mxcl/homebrew/issues/18256#issuecomment-15027174" target="_blank">here</a>.</p> <p>Cheers</p> http://andywenk.github.io/couchdb/2013/04/09/installing-couchdb-with-erlang-r16b-is-broken-here-is http://andywenk.github.io/couchdb/2013/04/09/installing-couchdb-with-erlang-r16b-is-broken-here-is 2013-04-09T09:01:00+00:00 [Talk] HH.js - Ruby on Rails Asset Pipeline <p>Moin Moin,</p> <p>yesterday I talked about the Ruby on Rails Asset Pipeline at HH.js. The <a href="https://github.com/andywenk/rails-asset-pipeline-hhjs-talk" target="_blank">slides are available here</a>, and Rainer Schleevoigt <a href="http://lecture2go.uni-hamburg.de/veranstaltungen/-/v/14785" target="_blank">taped the whole talk here</a>.</p> <p>Additionally you should really also watch Adam Hawkins talk about Ember.js. He showed the main aspects of Ember.js within an <a href="http://lecture2go.uni-hamburg.de/veranstaltungen/-/v/14786" target="_blank">awesome live coding session</a>. The video can be found here.</p> <p>So - have fun watching!</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/rails/2013/03/19/talk-hh-js-ruby-on-rails-asset-pipeline http://andywenk.github.io/rails/2013/03/19/talk-hh-js-ruby-on-rails-asset-pipeline 2013-03-19T15:47:56+00:00 <iframe src="http://www.tumblr.com/video/andywenk/45215146204/400" id="tumblr_video_iframe_45215146204" class="tumblr_video_iframe" width="400" height="225" style="display:block;background-color:transparent;overflow:hidden;" allowTransparency="true" frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe><br/><p>Kiana&#8217;s first jump from the 1m board!</p> <p>So damn&#8217; proud I am ;-)</p> http://andywenk.github.io/family/2013/03/12/kianas-first-jump-from-the-1m-board-so-damn http://andywenk.github.io/family/2013/03/12/kianas-first-jump-from-the-1m-board-so-damn 2013-03-12T21:34:38+00:00 using rvm aliases - <p>Moin Moin,</p> <p>let&#8217;s assume, you have many different Ruby&#8217;s for your projects and you want to keep your gems separate in each Ruby. The best way (in my experience) is to use different Ruby versions and use there the needed gems for this kind of application. An example:</p> <p>You have different Rails 2.3.17 applications. When running against a Mock, you use ruby-1.8.7-p371, when running against a WebService, you use jruby-1.7.2.</p> <p>Then you have different Rails 3.2.12 applications. When running against a Mock, you use ruby-1.9.3-p392, when running against a WebService, you use jruby-1.7.3.</p> <p>So this is what we&#8217;ve got so far:</p> <script src="https://gist.github.com/andywenk/5064886.js"></script><p>Well, to remember this, some unnecessary brain activity is needed. Let&#8217;s simplify that with creating some aliases:</p> <script src="https://gist.github.com/andywenk/5064902.js"></script><p>Nice. Now we could write rvm use salesm. But when using rvm list, we don&#8217;t see the aliases listed. Simple enough, we creat an alias in ~/.bashrc or ~/.bash_profile:</p> <script src="https://gist.github.com/andywenk/5064913.js"></script><p>Now we can see both results from rvm list and rvm alias list:</p> <script src="https://gist.github.com/andywenk/5064917.js"></script><p>Simple and helpful &#8230; isn&#8217;t it?</p> <p>Cheers</p> http://andywenk.github.io/server/2013/03/01/using-rvm-aliases http://andywenk.github.io/server/2013/03/01/using-rvm-aliases 2013-03-01T14:15:43+00:00 ruby alias and alias_method 1.8.x, 1.9.x, 2.0.x <p>Moin Moin,</p> <p>it took me a moment to understand how this is working. Actually there are no good examples for the usage of alias and alias_method in the w3 so I decided to post this here.</p> <p>The code for the examples can be found here: <a href="https://gist.github.com/andywenk/5038259" target="_blank"><a href="https://gist.github.com/andywenk/5038259" target="_blank">https://gist.github.com/andywenk/5038259</a></a></p> <p>Here is a basic example for the usage of <strong>alias</strong>:</p> <script src="https://gist.github.com/andywenk/5059628.js" type="text/javascript"></script><p>The output is:</p> <p><em>Example with the usage of alias</em><br/><em>I am the total perfect method</em></p> <p>The first thing to mention, is that this will not work, when one is writing the <em>alias</em> line before the <em>even_nicer_method</em>. The reason is, that <em>alias</em> is a Ruby keyword and is immediately executed, when the source is parsed. So the method <em>even_nicer_method</em> has to be declared in advance.</p> <p>Now an example for the usage of <em>alias_method</em>:</p> <script src="https://gist.github.com/andywenk/5059638.js" type="text/javascript"></script><p>The output is:</p> <p><em>Example with the usage of alias</em><br/><em>AliasMethod::even_nicer_method called</em></p> <p>On first sight, it seems to be the same. The big difference is found in scoping. Here is an example using inheritance which is working also in both ways:</p> <script src="https://gist.github.com/andywenk/5059644.js" type="text/javascript"></script><p>The output is for both alias and alias_method:</p> <p><em>Example for inheritance</em><br/><em>I am the Mother</em></p> <p>But when using class methods, things are changing:</p> <script src="https://gist.github.com/andywenk/5059647.js" type="text/javascript"></script><p>In this constructed situation, a class method <em>my_name</em> is defined in <em>MotherScope</em> and is beeing called in <em>ChildScope</em>. So the question is, how <strong>self</strong> is handled.</p> <p>The output when using alias in <em>MotherScope.my_name</em> is:</p> <p><em>Example for class methods in inheritance (scope!)</em><br/><em>I am the Mother</em></p> <p>The output when using alias_method in MotherScope.my_name is:</p> <p><em>Example for class methods in inheritance (scope!)</em><br/><em>I am the Child</em></p> <p>Why? Because when using alias, self is the thing when parsing the source code. That means, self &#8220;is pointing&#8221; to <em>MotherScope</em>. But when using <em>alias_method</em>, the scope is the one found during runtime!</p> <p>I hope this makes the usage and difference between alias and alias_method clear. While writing this I found these two posts - so yes there are at least some posts ;-):</p> <p><a href="http://andreacfm.com/2012/11/29/ruby-alias-vs-alias-method/" target="_blank"><a href="http://andreacfm.com/2012/11/29/ruby-alias-vs-alias-method/" target="_blank">http://andreacfm.com/2012/11/29/ruby-alias-vs-alias-method/</a></a></p> <p><a href="http://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html" target="_blank"><a href="http://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html" target="_blank">http://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html</a></a></p> <p>Cheers</p> http://andywenk.github.io/programming/2013/02/26/ruby-alias-and-alias-method-1-8-x-1-9-x-2-0-x http://andywenk.github.io/programming/2013/02/26/ruby-alias-and-alias-method-1-8-x-1-9-x-2-0-x 2013-02-26T12:37:00+00:00 git advanced config and shortcuts / aliases <p>Moin Moin,</p> <p>wow - two git related posts today ;-)</p> <p>I recently found a very nice page with helpful git settings. They are written by <a href="http://mislav.uniqpath.com/" target="_blank">Mislav Marohnic</a>. On the first page he is discussing Git merge vs. rebase:</p> <p><a href="http://mislav.uniqpath.com/2013/02/merge-vs-rebase/" target="_blank">http://mislav.uniqpath.com/2013/02/merge-vs-rebase/</a></p> <p>The second one is offering some nice tips when using git:</p> <p><a href="http://mislav.uniqpath.com/2010/07/git-tips/" target="_blank">http://mislav.uniqpath.com/2010/07/git-tips/</a></p> <p>So it should be a good thing to add some aliases to your ~/.gitconfig. Let&#8217;s say you wanna set the shortcut &#8216;pu&#8217; for pull but with an extra option to always use rebase when pulling:</p> <script src="https://gist.github.com/andywenk/5059677.js"></script><p>This helps you to avoid flooding your history with unnecessary merge commits.</p> <p>Here some helpful shortcuts taken from my ~/.gitconfig:</p> <script src="https://gist.github.com/andywenk/5059683.js"></script><p>I found an entry on stackoverflow giving some insight on how to use aliases: <a href="http://stackoverflow.com/questions/2553786/how-do-i-alias-commands-in-git" target="_blank">http://stackoverflow.com/questions/2553786/how-do-i-alias-commands-in-git</a></p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/server/2013/02/21/git-advanced-config-and-shortcuts-aliases http://andywenk.github.io/server/2013/02/21/git-advanced-config-and-shortcuts-aliases 2013-02-21T19:42:00+00:00 git tab-completion on Mac OS X when installed via homebrew <p>Moin Moin,</p> <p>on Mac OS X you do not have tab-completion in git. You have to activate it. Recently my colleauge Enrico found a description how to do so:</p> <p><a href="http://en.newinstance.it/2010/05/23/git-autocompletion-and-enhanced-bash-prompt/" target="_blank">http://en.newinstance.it/2010/05/23/git-autocompletion-and-enhanced-bash-prompt/</a></p> <p>This is cool but it will not work, when you have installed git via homebrew &#8230; what I strongly recommend. Here is what you have to add to your .bash_profile in your homedirectory:</p> <script src="https://gist.github.com/andywenk/5059691.js"></script><p>Make sure that the two files are executable (change it with chmod a+x [file]).</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/server/2013/02/21/git-tab-completion-on-mac-os-x-when-installed-via http://andywenk.github.io/server/2013/02/21/git-tab-completion-on-mac-os-x-when-installed-via 2013-02-21T13:57:00+00:00 Playframework: how to use moreScripts and moreStyles <h3>Moin Moin,</h3> <p>actually I am working with the <a href="http://www.playframework.org" target="_blank">http://www.playframework.org</a> in a project. It is MVC web-framework written in Java. I like it because it&#8217;s simple to understand. Ok - maybe better if you already have experience with frameworks like Django or Rails.</p> <p>What I did not understand a the first glimps is how to use moreScripts and moreStyles in main.html head:</p> <script src="https://gist.github.com/andywenk/5059702.js"></script><p>But it&#8217;s quite simple because with get one receives the content of a variable and with set, like the name indicates, one sets the value of a variable. The only difference to the variable title in the title-tag above is the fact, that a helper method for JavaScript and CSS files is available. This helper is also setting the path to the files:</p> <p>Example for moreScripts definition -&gt; public/javascripts</p> <script src="https://gist.github.com/andywenk/5059710.js"></script><p>Example for moreStyles definition -&gt; public/stylesheets</p> <script src="https://gist.github.com/andywenk/5059719.js"></script><p>Here is the documentation:</p> <p><a href="http://www.playframework.org/documentation/1.2.5" target="_blank">http://www.playframework.org/documentation/1.2.5</a></p> <p>Meno, a colleague told not to use anything else than Playframework 1.2.5. So at this moment, I follow this advice ;-) </p> <p>Cheers </p> <p>Andy</p> http://andywenk.github.io/programming/2013/02/05/playframework-how-to-use-morescripts-and-morestyles http://andywenk.github.io/programming/2013/02/05/playframework-how-to-use-morescripts-and-morestyles 2013-02-05T22:52:00+00:00 Happy new Year! <p>Ein bisschen mehr Friede und weniger Streit,<br/> Ein bisschen mehr Güte und weniger Neid,<br/> Ein bisschen mehr Liebe und weniger Hass,<br/> Ein bisschen mehr Wahrheit - das wäre doch was!</p> <p>Statt so viel Unrast ein bisschen mehr Ruh&#8217;,<br/> Statt immer nur Ich ein bisschen mehr Du,<br/> Statt Angst und Hemmung ein bisschen mehr Mut<br/> Und Kraft zum Handeln - das wäre gut!</p> <p>Kein Trübsal und Dunkel, ein bisschen mehr Licht,<br/> Kein quälend Verlangen, ein bisschen Verzicht,<br/> Und viel mehr Blumen, solange es geht,<br/> Nicht erst auf Gräbern - da blüh&#8217;n sie zu spät!</p> <p>(hat mir mein Dad zu Weihnachten geschickt &#8230; schön!)</p> http://andywenk.github.io/family/2013/01/03/happy-new-year http://andywenk.github.io/family/2013/01/03/happy-new-year 2013-01-03T08:57:00+00:00 removing a gem from @globals <p>Moin Moin,</p> <p>some minutes ago I hade the problem, that my gemset was fucked up. I am using rvm and I had to remove rake 10.0.3. So it works like this:</p> <pre><code>rvm use @global gem uninstall rake -v 10.0.3 rvm use @ gem uninstall rake -v 10.0.3 </code></pre> <p>Don&#8217;t forget to go back to the ruby version you used before with</p> <pre><code>rvm use 1.6.7 </code></pre> <p>or similar &#8230;</p> <p>Credits for this go to my fine colleague Enrico!</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/programming/2012/12/13/removing-a-gem-from-globals http://andywenk.github.io/programming/2012/12/13/removing-a-gem-from-globals 2012-12-13T16:43:00+00:00 Logic operators in Ruby <h1>Moin Moin,</h1> <p>sometimes it&#8217;s really helpful to use a REPL to make things clear while coding. So you could use the awesome <a href="http://repl.it/" target="_blank"><a href="http://repl.it/" target="_blank">http://repl.it/</a></a> Ruby shell or simply open your terminal and use <a href="http://www.ruby-lang.org/en/documentation/quickstart/" target="_blank">irb</a> or <a href="http://pryrepl.org/" target="_blank">pry</a>. I did it today with my colleague Jan to remember who logical operators work for Ruby.</p> <h4>1. What is the result when I use &amp;&amp; for two arrays?</h4> <pre> [1] pry(main)&gt; [1,2] &amp;&amp; [3,4] =&gt; [3, 4] </pre> <p>The reason is, that here you check if both expressions are true. Ruby checks if the first expression is true and then checks if the second is also true. If yes, the last checked expression is returned. If you would examine another array as the last one (e.g. [5,6]), this one would be returned. Obviously if any of the expressions would be nil, nil would be the result.</p> <h4>2. What is the result when I use || for two arrays?</h4> <pre> [2] pry(main)&gt; [1,2] || [3,4] =&gt; [1, 2] </pre> <p>Here the first result is returned because the whole expression is returning true if at least one expression is true. If the first expression would be nil, the second would be returned.</p> <h4>3. What is the result when I use &amp; for two arrays?</h4> <pre> [3] pry(main)&gt; [1,2] &amp; [3,4] =&gt; [] </pre> <p>It&#8217;s an empty array because the logic AND is checking, if one or more values of the array (in this case) are present in both arrays. So the next example shows that:</p> <pre> [4] pry(main)&gt; [1,2] &amp; [2,3,4] =&gt; [2] </pre> <p>Got it? Just think of the possibilities you have with that small size of code. For example you could use this operation to find all the unique values which are present in the first array AND the second array:</p> <pre> [5] pry(main)&gt; [1,2,2] &amp; [3,3,2,2,4] =&gt; [2] [6] pry(main)&gt; [1,2,2,3] &amp; [3,3,2,2,4] =&gt; [2, 3] </pre> <h4>4. What is the result when I use | for two arrays?</h4> <pre> [7] pry(main)&gt; [1,2] | [3,4] =&gt; [1, 2, 3, 4] </pre> <p>The logic OR is returning all results from expression one and two. The result in this case (!) is the same like you would add both arrays but for sure these are two different things!</p> <pre> [8] pry(main)&gt; [1,2] + [3,4] =&gt; [1, 2, 3, 4] </pre> <p>And here is a real nice thing when using logic OR. Look at this:</p> <pre> [9] pry(main)&gt; [1,2,2] | [3,3,4] =&gt; [1, 2, 3, 4] </pre> <p>Nice and obvious. The logic OR is returning all unique values from array one and two. Now the difference to the + operator is clear:</p> <pre> [10] pry(main)&gt; [1,2,2] + [3,3,4] =&gt; [1, 2, 2, 3, 3, 4] </pre> <p>Have fun!</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/programming/2012/10/17/logic-operators-in-ruby http://andywenk.github.io/programming/2012/10/17/logic-operators-in-ruby 2012-10-17T14:00:00+00:00 Install ruby 1.8.7 with rvm on Mac OS X 10.8 <p>Moin Moin,</p> <p>if you have trouble installing ruby 1.8.7 via rvm on Mac OS X 10.8 (Mountain Lion), please check out these advices from <a href="http://stackoverflow.com/users/232053/matteo-alessani" target="_blank">Matteo Alessani</a>:</p> <p><a href="http://stackoverflow.com/questions/11664835/mountain-lion-rvm-install-1-8-7-x11-error" target="_blank"><a href="http://stackoverflow.com/questions/11664835/mountain-lion-rvm-install-1-8-7-x11-error" target="_blank">http://stackoverflow.com/questions/11664835/mountain-lion-rvm-install-1-8-7-x11-error</a></a></p> <p>Short summary:</p> <ol><li>install X11 via <a href="http://xquartz.macosforge.org/landing/" target="_blank"><a href="http://xquartz.macosforge.org/landing/" target="_blank">http://xquartz.macosforge.org/landing/</a></a></li> <li>export CPPFLAGS=-I/opt/X11/include</li> <li>CC=/usr/local/bin/gcc-4.2 rvm reinstall 1.8.7</li> </ol><p>All credits for this to <a href="http://stackoverflow.com/users/232053/matteo-alessani" target="_blank">Matteo Alessani</a></p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/programming/2012/10/09/install-ruby-1-8-7-with-rvm-on-mac-os-x-10-8 http://andywenk.github.io/programming/2012/10/09/install-ruby-1-8-7-with-rvm-on-mac-os-x-10-8 2012-10-09T20:23:56+00:00 CouchDB monitoring with monit - really working! <p>Moin Moin,</p> <p>I have decided to use the latest development version of <a href="http://couchdb.apache.org/" target="_blank">CouchDB</a> (1.3.0a-272d641-git) on my machine. I am using CouchDB in a shop system to store user like contact requests. Nothing dramatical important.</p> <p>Since a lot of different software is running on this machine which is important for that shop and it&#8217;s availability is essential (like <a href="http://www.elasticsearch.org/" target="_blank">elasticsearch</a>), I decided to use <a href="http://mmonit.com/monit/" target="_blank">Monit</a> for monitoring and alerting.</p> <p>Unfortunately I could not get it working with CouchDB. And - surprise, surprise - CouchDB stopped working from time to time (btw - especially version 1.3.0a-72ea7e3-git). I had many approaches and I am aware that a correctly configured Erlang installation should fix the problem, because &#8220;heart&#8221; is taking the monitoring job for CouchDB. But - it still crashed.</p> <p>So now I am glad that I got it fixed and finally, it&#8217;s dead simple. Her is the (or better my, for me working) solution:</p> <pre><code>check process couchdb with pidfile /usr/local/var/run/couchdb/couchdb.pid group database start program = "/etc/init.d/couchdb start -u couchdb" stop program = "/etc/init.d/couchdb stop -u couchdb" if failed host 127.0.0.1 port 5984 then restart if cpu is greater than 40% for 2 cycles then alert if cpu &gt; 60% for 5 cycles then restart if 10 restarts within 10 cycles then timeout </code></pre> <p>This is the content of the file /etc/monit/conf.d/couchdb.conf and the most important parts are:</p> <ul><li>correct path to couchdb.pid</li> <li>start stop CouchDB as user couchdb (-u couchdb)</li> </ul><p>So if you have trouble with this and just found old or not for you working examples in the w3, check this one ;-)</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/couchdb/2012/09/19/couchdb-monitoring-with-monit-really-working http://andywenk.github.io/couchdb/2012/09/19/couchdb-monitoring-with-monit-really-working 2012-09-19T19:18:08+00:00 Rails ActiveRecord: difference between size and length when using DISTINCT <p>Moin Moin,</p> <p>actually I had a somehow strange behaviour in a quite costly SQL query. I am using pagination and there fore have to fire the query two times. One time without LIMIT and OFFSET and the second time with both of them. The full code can be found here:</p> <p><a href="https://gist.github.com/3746191" target="_blank"><a href="https://gist.github.com/3746191" target="_blank">https://gist.github.com/3746191</a></a></p> <p>I was wondering why the pagination is not correct. So I examined it. As you can see in row 16 and 17, I figured out that there is a difference between using size and length for the result of select_printer without LIMIT and OFFSET. So how does the SQL query look like. First I show the query for size:</p> <pre> =# SELECT COUNT(*) FROM "printers" INNER JOIN "manufacturers" ON "manufacturers"."id" = "printers"."manufacturer_id" INNER JOIN "printer_cartridges" ON "printer_cartridges"."printer_id" = "printers"."id" WHERE "manufacturers"."shortname" = 'brother' AND "printer_cartridges"."printer_group_id" = 19; count ------- 104 (1 row) </pre> <p>The result is 104 records. So Rails is simply not using my originally provided DISTINCT statement but instead using COUNT(*). Actually this is not what I want.</p> <p>Let&#8217;s see the difference when using length:</p> <pre> =# SELECT DISTINCT printers.id, printers.name FROM "printers" INNER JOIN "manufacturers" ON "manufacturers"."id" = "printers"."manufacturer_id" INNER JOIN "printer_cartridges" ON "printer_cartridges"."printer_id" = "printers"."id" WHERE "manufacturers"."shortname" = 'brother' AND "printer_cartridges"."printer_group_id" = 19 ORDER BY printers.name; id | name -----+------------ [...] (25 rows) </pre> <p>25 records is the correct result! I have no clue, why there is this difference. Do you have an idea?</p> <p>Btw - if you are calculating pages like I did it in line 26 using ceil, be aware that you have to cast both total and per_page to a float because 25 / 20 is 1 when both are integers ;-).</p> <p>Cheers</p> http://andywenk.github.io/rails/2012/09/18/rails-activerecord-difference-between-size-and-length http://andywenk.github.io/rails/2012/09/18/rails-activerecord-difference-between-size-and-length 2012-09-18T22:16:09+00:00 Sending email with Ruby (not Rails) <p>Moin Moin,</p> <p>this is a quicky. If you are looking for a tutorial about how to send an email with plain Ruby, check out this great blog post:</p> <p><a href="http://www.tutorialspoint.com/ruby/ruby_sending_email.htm" target="_blank"><a href="http://www.tutorialspoint.com/ruby/ruby_sending_email.htm" target="_blank">http://www.tutorialspoint.com/ruby/ruby_sending_email.htm</a></a></p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/programming/2012/09/09/send-email-with-ruby-not-rails http://andywenk.github.io/programming/2012/09/09/send-email-with-ruby-not-rails 2012-09-09T19:53:38+00:00 Why GIT is the only SCM you should use for your projects! <p>Moin Moin,</p> <p>after having been assimilated by SinnerSchrader in 2010, I started to use GIT on a daily basis and immediately loved it. I got in touch already when I played around with CouchApp because Benoit Chesneau used GIT for the source code. So I registered at github.com and started to use it.</p> <p>To be honest, the first SCM I used was CVS but that was in the days when my OS was stil Windows XP. I worked on a PHP project and the code was held in a CVS. I can remember that we used a GUI tool for it which was kind of crappy. And I can also remember, that we threw away the whole repository several times because of errors.</p> <p>After that we switched to SVN. That was quite good for our needs. Tortoise SVN is a nice integration into the Windows Explorer and I used that. But after throwing away fuckin&#8217; Windows finally and starting to use Ubuntu Linux, I was lost because there was no GUI for my SVN repos. So I started to learn the CLI for SVN and I liked it.</p> <p>I started to have a lot of SVN repos for all my projects. We even held the writings for our <a href="http://www.pg-praxisbuch.de/" target="_blank">PostgreSQL</a> book in a SVN repo. The experience I have with SVN is quite good. There are some ok possibilities to set access to repositories but you have to dig a little deeper to get them running. One big problem is the usage of branches. Well yes you can make branches, but merging them back to a main branch is a pain in the ass. So we did not use it and this is a big fail! Another thing is the lack of a local copy of the repository. The commit command is pushing always to the central repository most likely on a different machine, accessible via a internet connection. This means, that the source code is complete only at one physical place. This is a SPOF!</p> <p>GIT is the solution for all these caveats. I use a lot of features of GIT heavily. Sure, the standard stuff like log, add, commit, pull, push and so on. But also rebase, merge and submodules. And most important: branch.</p> <p>I strongly recommend using feature branches because it makes your life easier in many ways. You don&#8217;t have to fear, that you brake one of the main branches and you can leave the stuff on a branch for as long as it takes to finish your feature development work. Testing with the last available main branch is easy when you rebase the code base into your feature branch. When everything is done, you can shrink all the commits to one commit (with rebase -i [commit sha1] and merge it into the main branch. If something is wrong and the reason is the one feature branch commit, just rip it out of the main branch and everything is good again.</p> <p>Here is a little example of how such a feature branch work could be done (German &#8230; sorry): <a href="http://team7.sinnerschrader.de/2011/04/git-commits-mit-rebase-zusammenfassen.html" target="_blank">http://team7.sinnerschrader.de/2011/04/git-commits-mit-rebase-zusammenfassen.html</a></p> <p>The most important thing about the idea behind GIT is the fact, that GIT is distributed. There is no central main big repo. Everybody has this so called &#8220;main big repo&#8221; locally - or a part of it - or some branches - or just one branch. And you can work on it locally without the need to have a connection to the internet. If your work is done, you can push it to a place where others can pull from. And that&#8217;s it.</p> <p>Linus Torvalds is the creator of GIT. He developed it because some of his fellows asked him to use a SCM. In the early days he was just using tar-balls and patches and he is convinced, that doing it this way was better than using CVS, SVN and other tools because they all suck. Check out this really good talk at Google he gave about GIT:</p> <p><a href="https://www.youtube.com/watch?v=4XpnKHJAok8&amp;feature=player_embedded" target="_blank">https://www.youtube.com/watch?v=4XpnKHJAok8&amp;feature=player_embedded</a></p> <p>Well, here is the conclusion: use GIT!</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/server/2012/08/14/why-git-is-the-scm-you-should-use http://andywenk.github.io/server/2012/08/14/why-git-is-the-scm-you-should-use 2012-08-14T10:00:00+00:00 Ruby code analyzing rake tasks <p><strong>Moin Moin,</strong></p> <p>while writing Ruby code for the last three years now, I think I have a solid knowledge, how Ruby code and projects should be written. But who am I to think, that I do everything perfect. No. I know, that there are always flaws in my code, your code, everybody&#8217;s code.</p> <p>That&#8217;s the reason why there are code metric and analyzing tools for each programming language. For Ruby there are also several. I started using four of them. For convenience purposes, I created a small git repository with some rake tasks. You can find it <a href="https://github.com/andywenk/ruby_code_analyzer_rake_tasks" target="_blank">here on github</a>. I used it in the sample output below.</p> <h3>reek</h3> <p><a href="https://github.com/troessner/reek/wiki" target="_blank">https://github.com/troessner/reek/wiki</a></p> <p>reek is an awesome code smell detector written by <a href="https://twitter.com/kevinrutherford" target="_blank">Kevin Rutherford</a> and now maintained by <a href="https://github.com/troessner/reek" target="_blank">Timo Rößner</a>. It actually is looking for code smells like Duplication, Long Method, Large Class, Simulated Polymorphism and the like. <a href="https://github.com/troessner/reek/wiki/Code-Smells" target="_blank">Check out the code smells Wiki page </a>for more info. I strongly recommend optimizing your code to avoid these smells.</p> <p><strong>sample output</strong></p> <pre> $ rake analyzer:reek Running reek and find code smells app/controllers/application_controller.rb -- 2 warnings: ApplicationController has no descriptive comment (IrresponsibleModule) ApplicationController#render_500 has the name 'render_500' (UncommunicativeMethodName) app/controllers/news_controller.rb -- 2 warnings: NewsController has no descriptive comment (IrresponsibleModule) NewsController#save_newsletter_registration calls flash 3 times (DuplicateMethodCall) </pre> <h3>rails_best_practices</h3> <p><a href="http://rails-bestpractices.com" target="_blank">http://rails-bestpractices.com</a></p> <p>rails_best_practices is a tool to check the quality of Rails code. It is written by <a href="https://twitter.com/flyerhzm" target="_blank">@flyerhzm</a>. It tells you, where you can optimize your Rails code by providing detection for e.g. MoveModelLogicIntoModelReview, RemoveUnusedMethodsInControllersReview, ReplaceComplexCreationWithFactoryMethodReview and many others.</p> <p><strong>sample output</strong></p> <pre> $ rake analyzer:rails_best_practices Running rails_best_practices and inform about found issues Source Codes: 100% |ooooooooooo| Time: 0:00:02 app/models/image.rb:11 - change Hash Syntax to 1.9 app/models/image.rb:19 - change Hash Syntax to 1.9 app/controllers/pages_controller.rb:59 - move model logic into model (page use_count &gt; 4) app/controllers/admin/galleries_controller.rb:20 - remove unused methods (Admin::GalleriesController#create) </pre> <h3>flay</h3> <p><a href="http://ruby.sadi.st/Flay.html" target="_blank">http://ruby.sadi.st/Flay.html</a></p> <p>First of all, I really like the website of the <a href="http://ruby.sadi.st/About_Us.html" target="_blank">RubySadists</a>. I guess these two guys have a lot of fun working on Ruby projects.</p> <p>flay is detecting structural similarities in your code. The found issues are good candidates for refactoring.</p> <p><strong>sample output</strong></p> <pre> $ rake analyzer:flay Running flay and and analyze code for structural similarities flay app/* 1) Similar code found in :defn (mass = 87) app/controllers/admin/images_controller.rb:11 app/controllers/admin/news_controller.rb:19 app/controllers/admin/uploads_controller.rb:31 2) Similar code found in :defn (mass = 78) app/controllers/admin/galleries_controller.rb:45 app/controllers/admin/news_controller.rb:40 app/controllers/admin/uploads_controller.rb:41 </pre> <h3>flog</h3> <p><a href="http://ruby.sadi.st/Flog.html" target="_blank">http://ruby.sadi.st/Flog.html</a></p> <p>This also a library from the RubySadists. It simply shows you shitty code. This is a good starting point to rethink what the heck you have coded ;-). As an indicator, a number is used to show how ugly the code at the found line is. The higher the number, the worse it is.</p> <p><strong>sample output</strong></p> <pre> rake analyzer:flog Running flog and find the most tortured code flog -cad app/models/*.rb 130.7: flog total 4.4: flog/method average 11.8: Image#none 2.5: assignment 2.3: branch 1.5: max 1.4: sorting 1.3: + 1.2: nil? 1.1: before_save 1.1: mount_uploader 1.1: validates 1.1: belongs_to 1.1: attr_accessible 0.4: lit_fixnum 8.1: Image::json_data app/models/image.rb:17 1.6: array_of_images_with_id_and_path 1.4: [] 1.4: joins 1.2: where 1.2: new 1.2: assignment 1.2: to_json 8.0: ImageSorter#change_position app/models/image_sorter.rb:26 2.8: sorting 2.4: assignment 2.4: update_image </pre> <h3>summary</h3> <p>These four code metric tools are just a few out of a bunch of tools. But it&#8217;s always the same. It&#8217;s better than nothing. And here&#8217;s a challange: try to fix all found issues in one of your smaller projects. How longe did it take? A day? A week? A month? The most important part of the story is the fact, that you will remember what you did wrong the next time you open your code editor and start hacking on a Ruby project.</p> <p>Cheers</p> <p>Andy</p> <p>EDIT: you can see the analyzer in action here: <a href="http://shelr.tv/records/4ffa15da9660805a7a000005" target="_blank">http://shelr.tv/records/4ffa15da9660805a7a000005</a></p> http://andywenk.github.io/programming/2012/07/08/ruby-code-analyzing http://andywenk.github.io/programming/2012/07/08/ruby-code-analyzing 2012-07-08T15:15:00+00:00 Rails - debugging with pry <p>Moin Moin,</p> <p>debugging is one of the things a developer has to do most. One case is e.g when the customer is reporting a bug. Another one is when we are developing new software or features. Debugging is different in different languages. If you are coding Java, then it is pretty sure you are using Eclipse. It is offering a pretty good debugger inside the GUI. Developing JavaScript apps is less painless, since there are the great in-browser developer tools for <a href="https://www.google.com/intl/en/chrome/browser/" target="_blank">Google Chrome</a> or <a href="http://www.mozilla.org/en-US/firefox/new/" target="_blank">Mozilla Firefox</a>.</p> <p>Debugging in <a href="http://rubyonrails.org/" target="_blank">Rails</a> is not a pain in the ass. The <a href="http://rubygems.org/gems/ruby-debug" target="_blank">ruby-debug gem</a> is quite good. You have to start the local server with -u or &#8212;debugger. The debugger is stopping the program execution where you set the &#8216;debugger&#8217; method in your code. Inside the Rails log, there are then all the known debugger commands like &#8216;n&#8217; for next, &#8216;c&#8217; for continue and so on, available. In most cases this kind of &#8216;print_f&#8217; debugging is sufficient. There are some caveats or even shortcomings. Sometimes the scope of the debugger is wrong and you have to stop/start the server to fix this.</p> <p>Recently I stumbled upon an alternative for irb (the ruby interactive shell). It is called pry and can be found <a href="http://pry.github.com/" target="_blank">here</a>. The tool is super awesome and I strongly recommend that you give it a try. Here is a good <a href="http://railscasts.com/episodes/280-pry-with-rails" target="_blank">RailsCast from Ryan Bates</a>.</p> <p>The steps you have to do are simple:</p> <pre><code> gem install pry pry-doc </code></pre> <p>In your Gemfile add:</p> <pre><code> group :development do gem 'pry' ... end </code></pre> <p>Don&#8217;t forget to run bundle install afterwards.</p> <p>Now set the following to any place in your code - here is some example code from an AR model:</p> <pre><code> def printer_with_qraex_product printers = {} printer = select_printer total = printer.length printer = select_printer(true) printer.each do |p| cartridge = Cartridge.select('DISTINCT(qraexid)').where("printer_id=? and printer_group=?", p.id, group)[0] printers[p.name] = {qraexid: cartridge.qraexid} end binding.pry {:printer =&gt; printers, :total =&gt; total} end </code></pre> <p>'binding.pry' is the same as you would use 'debugger'. It is stopping the execution BUT also opening the pry shell and showing the code around the binding to pry:</p> <p><img src="http://media.tumblr.com/tumblr_m4ngcjjxHr1qa0m1w.png" alt=""/></p> <p>The cool thing is, that you now can access all the variables and methods in this scope:</p> <pre><code> [1] pry(#&lt;Printer&gt;)&gt; total =&gt; 2 [2] pry(#&lt;Printer&gt;)&gt; printer =&gt; [#&lt;Printer id: 37693, name: "Color InkJet CP 1160"&gt;, #&lt;Printer id: 37694, name: "Color InkJet CP 1700"&gt;] [3] pry(#&lt;Printer&gt;)&gt; </code></pre> <p>You can continue the execution of the program by entering &#8216;exit-all&#8217;</p> <h4>Conclusion</h4> <p>pry is an awesome tool - not only for debugging but also (and mainly) for inspecting objects. Give it a try and you will see, that as here discussed, debugging is much more efficient and fun.</p> http://andywenk.github.io/rails/2012/05/26/rails-debugging-with-pry http://andywenk.github.io/rails/2012/05/26/rails-debugging-with-pry 2012-05-26T22:00:00+00:00 Some good links <h3>Moin Moin,</h3> <p>here are some links.</p> <h4>Wiki book about implementing algorithms:</h4> <p><a href="http://en.wikibooks.org/wiki/Algorithm_Implementation" target="_blank">http://en.wikibooks.org/wiki/Algorithm_Implementation</a></p> <h4>Rails httparty gem for easy usage of the <a href="http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html" target="_blank">net::http classes</a></h4> <p><a href="https://github.com/jnunemaker/httparty" target="_blank">https://github.com/jnunemaker/httparty</a></p> <h4>a summary of some interestin IT blogs</h4> <p><a href="http://drtomcrick.wordpress.com/2012/05/07/a-set-of-top-computer-science-blogs/?utm_source=hackernewsletter&amp;utm_medium=email" target="_blank">http://drtomcrick.wordpress.com/2012/05/07/a-set-of-top-computer-science-blogs/?utm_source=hackernewsletter&amp;utm_medium=email</a></p> <h4>Skorks blog from Alan Skorkin about software development related stuff</h4> <p><a href="http://www.skorks.com/" target="_blank">http://www.skorks.com/</a></p> http://andywenk.github.io/programming/2012/05/12/some-good-links-about-it http://andywenk.github.io/programming/2012/05/12/some-good-links-about-it 2012-05-12T22:38:00+00:00 CouchDB introduction for JUG-Ostfalen <p>Moin Moin,</p> <p>last Thursday I had the opportunity to talk about <a href="http://apache.couchdb.org" target="_blank">CouchDB</a> at the <a href="http://www.jug-ostfalen.de/?page_id=10" target="_blank">JUG-Ostfalen</a>. <a href="https://twitter.com/#!/tanwien" target="_blank">Uwe Sauerbrei</a>, the organiser, asked me several weeks ago if I am interested to tell some Java geeks, that CouchDB is cool. And as we know - CouchDB and NoSQL is definitely cool.</p> <p>The talk was really nice. Around 35 people attended and have been really interested in the concepts of NoSQL databases and CouchDB in special. At the beginning I was asking who knows CouchDB (3), mongoDB (2), neo4J (5) or have at least heard about NoSQL database. Not too many did so. That was kind of amazing to me. Maybe because I am kind of in that movement and have a straight focus to Internet technologies and do not really imagine, that one does not know about NoSQL databases. But hey - thats totally fine for sure. Cool that a lot of questions had been asked.</p> <p>As <a href="http://twitter.com/klimpong" target="_blank">Till Klampaecke</a>l and me have been writing the <a href="http://www.couchdb-buch.de" target="_blank">German CouchDB book</a>, I had the chance to give away some copies. This is really cool, because it showed, that I could raise some interest. I hope they like the book ;-)</p> <p>I am looking forward to talk again about CouchDB. I have planned to also give a brief introduction to <a href="http://kan.so" target="_blank">kan.so</a>, a cool tool to build CouchApps, at this evening. But because we had to drive 1:45 h back to Hamburg I had only 2 h for the talk. So kan.so next time &#8230;</p> <p>If you&#8217;re interested in hearing some CouchDB stuff in an event you organise, go ahead an ask me or Till at <a href="http://www.couchdb-buch.de" target="_blank"><a href="http://www.couchdb-buch.de" target="_blank">http://www.couchdb-buch.de</a></a>.</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/couchdb/2012/05/12/couchdb-introduction-jug-ostfalen http://andywenk.github.io/couchdb/2012/05/12/couchdb-introduction-jug-ostfalen 2012-05-12T08:01:00+00:00 CouchDB Buch Website <p>Moin Moin,</p> <p>Till Klampaeckel und ich haben ein Buch über CouchDB geschrieben. Es ist im Galileo Computing Verlag erschienen. Till hat ausserdem eine coole website mit vielen Informationen, Code und Links zum Buch erstellt. Einfach mal hier gucken:</p> <p><a href="http://www.couchdb-buch.de" target="_blank"><a href="http://www.couchdb-buch.de" target="_blank">http://www.couchdb-buch.de</a></a></p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/couchdb/2011/12/17/couchdb-buch-website http://andywenk.github.io/couchdb/2011/12/17/couchdb-buch-website 2011-12-17T21:29:59+00:00 Image Manipulation with Ruby gem MiniMagick <p>Moin Moin,</p> <p>in a recent project, I have to resize uploaded images because the images have to be shown in a gallery. The user who uploads the image likes comfort, so I started to use</p> <p><a href="https://github.com/jnicklas/carrierwave" target="_blank">https://github.com/jnicklas/carrierwave</a></p> <p>for handling the upload and</p> <p><a href="https://github.com/probablycorey/mini_magick" target="_blank">https://github.com/probablycorey/mini_magick</a></p> <p>to resize the images in the upload process. MiniMagick is a wrapper for the cli tool</p> <p><a href="http://www.imagemagick.org/" target="_blank">ImageMagick</a></p> <p>well known for its huge image editing possibilities</p> <p>If you just need basic resizing, carrierwave can do the job for you as well.</p> <p>Here&#8217;s a simple example (taken from the github site). The script is called magic.rb and there is a image called input.jpg in the same folder. where I run the script:</p> <pre> #!/usr/bin/env ruby require 'rubygems' require 'mini_magick' image = MiniMagick::Image.open("input.jpg") image.resize "100x100" image.write "output.jpg" puts "width: #{image[:width]}" puts "height: #{image[:height]}" puts "compression: #{image["%Q"]}" </pre> <p>The output is:</p> <pre> duke@Macintosh:~/workspace/programming/ruby/MiniMagick$ ./magic.rb width: 71 height: 100 compression: 99 </pre> <p>Simple! But the one thing I wanna point you to is the following line in magic.rb:</p> <pre> puts image["%Q"] </pre> <p>This is cool, because you can use the format options provided by ImageMagick. You can find a list of all options at</p> <p><a href="http://www.imagemagick.org/script/escape.php." target="_blank">http://www.imagemagick.org/script/escape.php.</a></p> <p>So again a cool gem which saves hours of work!</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/programming/2011/12/10/image-manipulation-with-ruby-gem-minimagick http://andywenk.github.io/programming/2011/12/10/image-manipulation-with-ruby-gem-minimagick 2011-12-10T22:12:00+00:00 How Browsers Work Article (Tali Garsiel) <p>Moin Moin,</p> <p>I recently read the super awesome article &#8220;How Browsers Work&#8221; here:</p> <p><a href="http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/" target="_blank"><a href="http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/" target="_blank">http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/</a></a> </p> <p>Paul Irish cleaned up the original article written by Tali Garsiel, an Israeli developer. You can find her article here:</p> <p><a href="http://taligarsiel.com/Projects/howbrowserswork1.htm" target="_blank"><a href="http://taligarsiel.com/Projects/howbrowserswork1.htm" target="_blank">http://taligarsiel.com/Projects/howbrowserswork1.htm</a></a></p> <p>I strongly recommend all people who develop software for the web to read this article. It provides a great look behind the scenes of how browsers work. The topics are:</p> <p>_ the rendering engine - processing the HTML document<br/> _ the parser with it&#8217;s lexical and syntax analysis - the lexer (tokenizer) creating tokens and the parser constructing the pars-tree by applying syntax rules<br/> _ the HTML parser based on a DTD<br/> _ the resulting DOM-tree after parsing HTML<br/> _ the parsing algorithm of the HTML Parser <br/> _ the tokenization algorithm <br/> _ the tree construction algorithm creating elements of the resulting DOM-tree and each of it&#8217;s token<br/> _ CSS parsing<br/> _ render tree construction<br/> _ creating the layout (or reflow) out of the render tree<br/> _ the painting process - display the content elements by traversing the created render-tree<br/> _ the CSS2 visual model</p> <p>This is a lot of stuff and actually I am reading the article the second time. Imho the biggest benefit of studying the article is the deeper understanding how all the components of a browser work together to present the resulting website. </p> <p>Here are some links I extracted for further reading.</p> <p>_ The webkit rendering engine used by Chrome and Safari browsers: <a href="http://www.webkit.org/" target="_blank">http://www.webkit.org/</a></p> <p>_ context free grammar: <br/> <a href="http://en.wikipedia.org/wiki/Context-free_grammar" target="_blank">http://en.wikipedia.org/wiki/Context-free_grammar</a></p> <p>_ Flex parser generator:<br/> <a href="http://en.wikipedia.org/wiki/Flex_lexical_analyser" target="_blank">http://en.wikipedia.org/wiki/Flex_lexical_analyser</a></p> <p>_ Bison parser generator: <br/> <a href="http://www.gnu.org/software/bison/" target="_blank">http://www.gnu.org/software/bison/</a></p> <p>_ HTML5 specification: <br/> <a href="http://dev.w3.org/html5/spec/Overview.html" target="_blank">http://dev.w3.org/html5/spec/Overview.html</a></p> <p>_ WHATWG community working on HTML: <br/> <a href="http://www.whatwg.org/" target="_blank">http://www.whatwg.org/</a></p> <p>_ parsing HTML: <br/> <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html" target="_blank">http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html</a></p> <p>_ HTML syntax: <br/> <a href="http://www.w3.org/TR/html5/syntax.html#html-parser" target="_blank">http://www.w3.org/TR/html5/syntax.html#html-parser</a></p> <p>_ CSS2: <br/> <a href="http://www.w3.org/TR/CSS2/" target="_blank">http://www.w3.org/TR/CSS2/</a></p> <p>_ CSS specification: <br/> <a href="http://www.w3.org/TR/CSS2/grammar.html" target="_blank">http://www.w3.org/TR/CSS2/grammar.html</a></p> <p>_ CSS2 box-model: <br/> <a href="http://www.w3.org/TR/CSS2/box.html" target="_blank">http://www.w3.org/TR/CSS2/box.html</a></p> <p>Some of the links are kind of lame to read in a way but still very interesting for digging deeper.</p> <p>I hope you enjoy reading the article the same way I do.</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/www/2011/08/30/how-browsers-work-by-tali-garsiel http://andywenk.github.io/www/2011/08/30/how-browsers-work-by-tali-garsiel 2011-08-30T20:46:00+00:00 git - squashing commits <p>Moin Moin,</p> <p>because I can&#8217;t fuckin&#8217; remember this cool git feature, I have to write it down shortly.</p> <p>Let&#8217;s say you have some commits made to a specific branch. Firing git log could return something like this:</p> <pre> commit dfc1aa75553b796e94a0927575721f8b1938e53a Author: Andreas Wenk <andreas.wenk> Date: Mon Apr 4 11:44:50 2011 fourth line commit 873a784e13b8d333f17ba805260cdd275ec962b2 Author: Andreas Wenk <andreas.wenk> Date: Mon Apr 4 11:44:10 2011 third line commit fe1eb9eab73062256bc1e6131826c8698c090f70 Author: Andreas Wenk <andreas.wenk> Date: Mon Apr 4 11:43:34 2011 second line commit f3ea5367b7c20334b5844b5eabb450374db57501 Author: Andreas Wenk <andreas.wenk> Date: Mon Apr 4 11:43:00 2011 first line </andreas.wenk></andreas.wenk></andreas.wenk></andreas.wenk></pre> <p>Now these commits are kind of the same and I decide to put some of them into one commit to not flooding the git log history. The command you&#8217;re looking for is <i>git rebase -i</i></p> The target is to make one commit out of the three newest commits. git-rebase needs one commit point, after which the operations shall be done. So what we write is: <pre> git rebase -i e2148eac05 </pre> The resulting output is: <pre> pick fe1eb9e second line pick 873a784 third line pick dfc1aa7 fourth line # Rebase f3ea536..dfc1aa7 onto f3ea536 # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. # </pre> The first thing you should recognize is that the commit history is in reverse order. So the oldest is on top. Now we wanna squash these three commits to one. git-rebase offers some commands you can put in front of each commit line. What we need is s for squash or f for fixup. The commands are slightly different. squash will not discard the commit but meld it into the previous one. Let&#8217;s do it: <pre> pick fe1eb9e second line s 873a784 third line s dfc1aa7 fourth line # Rebase f3ea536..dfc1aa7 onto f3ea536 # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. # </pre> <p>Here, we tell git, that the commit fe1eb9e is the one we wanna keep. You could also use another one. After saving this file git is providing another view:</p> <pre> # This is a combination of 3 commits. # The first commit's message is: second line # This is the 2nd commit message: third line # This is the 3rd commit message: fourth line # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # Not currently on any branch. # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: test # </file></pre> <p>Now, you have the opportunity to change the commit message. Use your fantasy to write a meaningful commit message. E.g:</p> <pre> # This is a combination of 3 commits. squashing togehter three commits # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # Not currently on any branch. # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: test # </file></pre> <p>Yeah - very meaningful ;-). Now save the file and git will do the work for you:</p> <pre> $ git rebase -i f3ea5367b7 [detached HEAD a17cc44] squashing togehter three commits 1 files changed, 6 insertions(+), 1 deletions(-) Successfully rebased and updated refs/heads/master. </pre> <p>And finally git log is telling us:</p> <pre> commit a17cc448869b0b092601f59da76970e1dd8e94e7 Author: Andreas Wenk <andreas.wenk> Date: Mon Apr 4 11:43:34 2011 squashing togehter three commits commit f3ea5367b7c20334b5844b5eabb450374db57501 Author: Andreas Wenk <andreas.wenk> Date: Mon Apr 4 11:43:00 2011 first line </andreas.wenk></andreas.wenk></pre> <p>Important note: this is a real powerful tool for manipulating the commit history. So you should <i>think</i> before <i>doing</i>. Especially when pushing the changed commits to an origin master where other people have worked on. Probably you will be told, that the pushing is rejected and you will have to use &#8212;force. This can imply damage &#8230;</p> <p>Happy squashing!</p> http://andywenk.github.io/server/2011/04/04/git-squashing-commits http://andywenk.github.io/server/2011/04/04/git-squashing-commits 2011-04-04T10:13:00+00:00 plain text transforming with pandoc and markdown Moin Moin, <p>actually we are writing a <a href="http://couchdb-buch.de" target="_blank">CouchDB book</a>. Today I was starting to read the whole book and make some notes which todo&#8217;s we have. I was thinking how I write them down - means in which format. No question that it will be a plain text format anyway.</p> <p>I decided to use <a href="http://daringfireball.net/projects/markdown/" target="_blank">markdown</a> because it&#8217;s really simple and easy to transform. Yes transform because of three reasons:</p> <ul><li>actually I don&#8217;t know which format I need later</li> <li>github.com does transform it to HTML</li> <li>it could be also transformed to LaTex</li> </ul><p>So how to transform the markdown. There is a really powerfull programm called <a href="http://johnmacfarlane.net/pandoc/" target="_blank">pandoc</a> written by John MacFarlane. pandoc is able to transform from various plain text formats to various other formats. E.g it&#8217;s easy to transform markdown to HTML.</p> <p>As a Mac OS X user I was first looking in <a href="http://mxcl.github.com/homebrew/" target="_blank">homebrew</a> if there is a package - unfortunately there isn&#8217;t yet. So I had to use <a href="http://www.macports.org/" target="_blank">MacPorts</a>. Be sure to update the ports tree because pandoc is changing rapidly. So use sudo port selfupdate, sudo port upgrade outdated and then sudo port install pandoc.</p> <p>So after having installed pandoc the usecase is quite simple illustrated. I have a simple textfile called TODO.md with some content. The first target is to create a html file. The creation process is as easy as this:</p> <pre> $ pandoc -s -t html -5 -f markdown -o TODO.html TODO.md </pre> <p>The options are: </p><ul><li>-s -&gt; we want a complete html file with enclosing &lt;html&gt;&lt;/html&gt; tags and not only a html snippet.</li> <li>-t html -&gt; the output format is html</li> <li>-5 -&gt; use html5</li> <li>-f markdown -&gt; the input format is markdown</li> <li>-o TODO.html -&gt; the file to be written</li> <li>TODO.md as the last option is the input file</li> </ul><p>Well the result is really good. Try it yourself.</p> <p>Well the next target is to create a PDF file. So therefor, a detour over LaTex is required. But don&#8217;t worry, it&#8217;s dead simple because pandoc is shipped with a program called markdown2pdf. Assuming you have LaTex installed, take these steps:</p> <pre> $ markdown2pdf TODO.md -o TODO.pdf </pre> <p>Wow - the result is a PDF TODO.pdf. Cool isn&#8217;t it?</p> <p>Cheers</p> Andy http://andywenk.github.io/server/2011/03/07/plain-text-transforming-with-pandoc-and-markdown http://andywenk.github.io/server/2011/03/07/plain-text-transforming-with-pandoc-and-markdown 2011-03-07T18:15:00+00:00 I love my Mac and iPad but ... <p>&#8230; I hate fucking iTunes. This bullshit software is just annoying me and makes me absolutely angry. </p> <p>The usability is simply crap and what really made me nuts was the fact, that I did not find a - &#8220;Mac makes it simple&#8221; - way to move purchased Apps from the iPad to the Mac.</p> <p>Ok - connecting the iPad to the MBP opens iTunes. And the ipad is mounted. So far so good. And I can see everything on the iPad. Cool. But why the fuck is it not possible to drag, let&#8217;s say, two or three apps and move them to iTunes? I don&#8217;t get it!</p> <p>Noooooo - please right click the iPad in the left menu and choose &#8220;Transfer Purchases&#8221;. Apple - come on. Why are you doing such a lousy job? This is just the biggest bullshit I experienced with iTunes - beside the other bullshit with this software.</p> http://andywenk.github.io/bullshit/2011/02/02/itunes-is-crap http://andywenk.github.io/bullshit/2011/02/02/itunes-is-crap 2011-02-02T21:10:51+00:00 CouchDB article in Entwickler Magazin 1.2011 <p>Moin Moin,</p> <p>I wrote another article about CouchDB. This time for the German Entwickler Magazin. I am showing the basic functionality for using map / reduce. </p> <p><a href="http://entwickler-magazin.de/" target="_blank">entwickler-magazin.de issue 1.2011</a></p> <p>All the best for 2011!</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/couchdb/2010/12/29/couchdb-article-in-entwickler-magazin-1-2011 http://andywenk.github.io/couchdb/2010/12/29/couchdb-article-in-entwickler-magazin-1-2011 2010-12-29T12:41:59+00:00 Playing with JavaScript callbacks <h4>Moin Moin,</h4> <p>while watching a stupid film in TV, what can you better do than playing with Firebug&#8217;s JS console. Actually I played with callbacks. Here ist what I did:</p> <pre> console.log("FIRST WAY:") var fn = (function(param) { console.log("param in fn (first way): " + param); }('bla')); var action = function(callback) { callback; } console.log("calling action:"); action(fn); console.log("action is a: " + typeof action); console.log("fn is a: " + typeof fn); console.log(" ") console.log("OTHER WAY:") var fn = function(param) { console.log("param in fn (other way): " + param); } var action = function(callback) { var param = 'other way'; callback(param); } console.log("calling action:"); action(fn); console.log("action is a: " + typeof action); console.log("fn is a: " + typeof fn); </pre> <p>Result:</p> <pre> FIRST WAY: param in fn (first way): bla calling action: action is a: function fn is a: undefined OTHER WAY: calling action: param in fn (other way): other way action is a: function fn is a: function </pre> <p>Hm - what&#8217;s that? Yeah - just playing around. Actually there are two things which are kind of interesting. First, the anonymous function is called immediately after it was built. Even though it is held in a variable (fn).<br/> The second thing is, that the typeof fn is undefined. Hm &#8230; I don&#8217;t know why at the moment I am writing this. I would expect it is a string. I will examine this further.</p> <p>One side note: you have to call the callback in action() in the first approach as a string because it&#8217;s not a function - that&#8217;s why I assume it should be typeof string. </p><p>The conclusion is: don&#8217;t use the first way because it does not work and does not make sense at all.</p> http://andywenk.github.io/programming/2010/11/28/callbacks-in-javascript http://andywenk.github.io/programming/2010/11/28/callbacks-in-javascript 2010-11-28T20:46:57+00:00 CouchDB Article in German PHP Magazin online <p>Moin Moin,</p> <p>I just got the info, that my CouchDB article from German PHP Magazine 5.10 is available online:</p> <p><a href="http://it-republik.de/php/artikel/Ein-PHP-Wrapper-fuer-die-CouchDB-3463.html" target="_blank"><a href="http://it-republik.de/php/artikel/Ein-PHP-Wrapper-fuer-die-CouchDB-3463.html" target="_blank">http://it-republik.de/php/artikel/Ein-PHP-Wrapper-fuer-die-CouchDB-3463.html</a></a></p> <p>You&#8217;ll read some basic stuff &#8216;bout CouchDB and I show a simple way, how to build a PHP wrapper for basic CouchDB operations like adding, updating or deleting documents.</p> <p>Btw: you should have a look to the <a href="http://docs.couchone.com/" target="_blank">new couchone CouchDB API</a>!</p> <p>Comments are very welcome.</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/couchdb/2010/11/25/couchdb-php-wrapper-php-magazin http://andywenk.github.io/couchdb/2010/11/25/couchdb-php-wrapper-php-magazin 2010-11-25T08:44:00+00:00 Kongo Skulls live 13.11.2010 Platzhirsch Hamburg <p>Moin Moin,</p> <p>my good friends from<a href="http://www.kongo-skulls.de" target="_blank"> Kongo Skull</a>s are playing a gig in Hamburg this month. Check it out and come over to drink beers &#8230;.</p> <p><img src="http://media.tumblr.com/tumblr_lb77g9w78e1qa0m1w.jpg"/></p> http://andywenk.github.io/music/2010/11/01/kongo-skulls-reeperbahn-hamburg-platzhirsch http://andywenk.github.io/music/2010/11/01/kongo-skulls-reeperbahn-hamburg-platzhirsch 2010-11-01T08:56:29+00:00 Promote JS! <h4>Moin Moin,</h4> <p>maybe the most important thing I took back home from #jsconf last weekend is the &#8220;deep from the heart&#8221; Community JS speech by Chris Williams (<a href="http://www.twitter.com/voodootikigod" target="_blank">@voodootikigod</a>) with the call to Promote JS:</p> <div style="text-align:center"><a href="https://developer.mozilla.org/en/JavaScript" title="JavaScript Reference, JavaScript Guide, JavaScript API, JS API, JS Guide, JS Reference, Learn JS, JS Documentation" target="_blank"><img src="http://static.jsconf.us/promotejshs.png" height="150" width="180" alt="JavaScript Reference, JavaScript Guide, JavaScript API, JS API, JS Guide, JS Reference, Learn JS, JS Documentation"/></a></div> <p>Go, do the same and get the code here: <a href="http://promotejs.com" target="_blank"><a href="http://promotejs.com" target="_blank">http://promotejs.com</a></a></p> <h4>Arrrrrrrrrr</h4> <p>Andy (<a href="http://www.twitter.com/awenkhh" target="_blank">@awenkhh</a>)</p> http://andywenk.github.io/programming/2010/09/28/promote-js http://andywenk.github.io/programming/2010/09/28/promote-js 2010-09-28T17:27:49+00:00 Migrating my IMAP mailbox to Google Mail with larch <p>Moin Moin,</p> <p>recently I decided to migrate my IMAP mailbox, hosted on one of our server, to Google Mail. There are a lot of advantages using Google Mail or any other (good) web based client. I decided to use Ryan Grove&#8217;s <a href="http://github.com/rgrove/larch" target="_blank">larch</a> Ruby program to get the job done.</p> <p>There is also <a href="http://www.linux-france.org/prj/imapsync/" target="_blank">imapsync</a> written by Gilles Lamiral in PERL. </p> <p> Everything went quite well besides the fact, that Google is obviously using their own interpretation of the IMAP mailbox folder. I had a lot of issues with subfolders and took the time to move every mail into INBOX.subfolder. Not deeper. </p> <p> Ok quite a lot of work because my mailbox is 2.8&#160;GB big. But what the heck. You don&#8217;t really need a subfolder subfolder in a subfolder structure because Google Mail is using labels for marking emails. And don&#8217;t forget that there is a really powerful fulltext search. So keep it simple and forget about the subfolder insanity. </p> <p> The cool thing is the fact, that larch is available as a <a href="http://rubygems.org/" target="_blank">gem</a>. So you need ruby (you already have it or you can install it with the supported package manager of your OS) and rubygems. After installing both, simply type: </p> <pre> $ gem install larch </pre> <p> That&#8217;s it. A simple command for transfering a mailbox to google is looking like this: </p> <pre> $ larch --from imap://mail.server.com --to imaps://imap.googlemail.com --from- \ <br/>folder 'INBOX.Andy' --to-folder 'Andy' </pre> <p> This would transfer every mail found in the folder Andy of your IMAP mailbox to a folder Andy in Google mail. After firing this command, you will be promted to give your login credentials of both your IMAP mailbox and of your Google Mail account. </p> <p> You can also use a config file where you write in your credentials and some migration (folder) information. The file can be found in /home/you/.larch/config.yaml. Note that some options are only available in the latest dev version. </p> <p> One good thing more. Larch is tracking the status of the transfer of each email in a sqlite3 database (alos in the .larch folder). So in the normal case, no email will be transfered twice but if the email was not already transfered, larch is trying to do so in a second attempt. </p> <p> My feedback is simple: this is a very easy to use tool and is helping a lot for migrating a IMAP email box to another server. Thanks Ryan &#8230; </p> Andy http://andywenk.github.io/server/2010/09/15/larch-migrat-imap-mailbox-to-google-mail http://andywenk.github.io/server/2010/09/15/larch-migrat-imap-mailbox-to-google-mail 2010-09-15T21:40:00+00:00 Start eclipse from the command line Hi, just a short tip if you want to start eclipse from the command line. You can find the possible options here: <a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.platform.doc.user/tasks/running_eclipse.htm" target="_blank"><a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.platform.doc.user/tasks/running_eclipse.htm" target="_blank">http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.platform.doc.user/tasks/running_eclipse.htm</a></a> Example: <pre> #!/bin/bash $HOME/applications/ver/eclipse/eclipse -clean -nosplash \ -data $HOME/project/ver/ </pre> Cheers Andy http://andywenk.github.io/programming/2010/09/09/start-eclipse-from-commandline http://andywenk.github.io/programming/2010/09/09/start-eclipse-from-commandline 2010-09-09T08:28:00+00:00 Shit about "Sh*t My Dad Says" <p>Moin Moin,</p> <p>it&#8217;s been a while since I wrote here. A lot of changes have happened &#8230; good changes. Maybe I find it interesting enough one day and I will write about it here.</p> <p>I am reading a lot. Mostly technical stuff about programming and databases. But once in a while I am getting annoyed about reading code and stuff. So I start reading a novel or &#8230; or a book I found while reading my <a href="http://twitter.com/awenkhh" target="_blank">Twitter timeline</a>. The one I found lately is Justin Halpern&#8217;s <a href="http://shitmydadsays.com" target="_blank">"Sh*t My Dad Says"</a>. You&#8217;ll read my impressions about the book here. </p> <p>First I thought, ah cool - I love bad ass speaking like &#8220;what the fuck - I am to old for that shit!&#8221;. And Justin&#8217;s dad is one of the best speaker in this manner I know (another one is Zakk Wylde who founded the metal band &#8220;Black Label Society&#8221; and former lead guitarist of Ozzy). I started reading and just laughed and laughed nearly each line. The style of writing is very entertaining and easy. You can relax and simply enjoy. </p> <p>But while reading more and more, it was not only the funny shit coming out of Justin&#8217;s dad&#8217;s mouth, but also I started realizing, that this man, is really a very good guy. He has a strong opinion about what is right and what is wrong and is taking a busload full of care about his son and his family. That impressed me a lot.</p> <p>Yes he is a severely father. In a way he remind me of my own dad. When I was younger, sometimes I was really angry, that my dad was that severely with me. But when I was becoming older (I mean up from 25 or something), I understood, that the only reason for him being severely with me, was to take care of me and always wanting the best for me. Today I know that he is really proud of me and helped me a lot becoming that person I am today. It was damn right what he did and how he was! I hope I can carry this to my own kids in a similar way.</p> <p>Probably the best chapter of &#8220;Sh*t My Dad Says&#8221; is the last one. The chapter is basically about the dad saying some good father words about how to mange the fact, that Justin was loosing his girlfriend he was already intended to marry. His dad spoke about his own life and a similar situation deep from his heart. Later, he showed his son the deep love he&#8217;s got for him. To be honest, my eyes went wet. This man is full of love, pride and gratitude for his son and his family. It always does impress me a lot when people have and show these values. And these values are also very important to me.<br/> Actually Justin&#8217;s Dad asked (or better instructed ;-) ) him to put this content in the last chapter because he thought it&#8217;s really important and for understanding the man Samuel Halpern. </p> <p>In short - this is as a very personal book written by a guy how is extremely proud and thankful of his dad. Go and get your copy! It&#8217;s worth each penny &#8230;</p> <p>P.S.: Thank you dad! I love you!</p> http://andywenk.github.io/reading/2010/05/16/shit-my-dad-says http://andywenk.github.io/reading/2010/05/16/shit-my-dad-says 2010-05-16T19:23:00+00:00 PHPucEU takes place in Manchester <p>Moin Moin,</p> <p>last evening, the organizers of the <a href="http://www.phpuceu.org/" target="_blank">PHPucEU</a> had another Skype session. The most important result is the fact, that we decided to let PHPucEU take place in Manchester next year. At the moment, the weekend of 29th to 30th January is our working date. We know spread this date and hope to get a lot of feedback if that date will fit for most people.</p> <p>See the blog post about yesterday&#8217;s meeting at the <a href="http://www.phpuceu.org/2010/04/19/looking-for-the-right-date/" target="_blank">official PHPucEU blog</a>.</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/programming/2010/04/20/phpuceu-in-manchester-january-2011 http://andywenk.github.io/programming/2010/04/20/phpuceu-in-manchester-january-2011 2010-04-20T08:34:56+00:00 First PHPucEU meeting in 2010 <p>Moin Moin,</p> <p>as I mentioned earlier, I am part of the organization team for the <a href="http://www.phpuceu.org/" target="_blank">European PHP Unconference</a>. Unfortunately I could not attend at the kick off meeting last year. So last night, we had the first Skype telco for this year. Judith (head of the team), Jonathan, Markus and myself were speaking about the main important topics like location, date, sponsoring and management. </p> <p>Everything seems quite promising and we decided, that due to other conferences, the best date for the conference will be in early 2011.</p> <p>I invite you to read a little more about the meeting yesterday at the <a href="http://www.phpuceu.org/2010/04/07/one-step-nearer-to-the-unconference/" target="_blank">official website</a>.</p> <p>Also, please feel free to follow us on twitter:</p> <p><a href="http://www.twitter.com/phpuceu" target="_blank">@phpuceu</a> <br/><a href="http://www.twitter.com/janosch007" target="_blank">@janosch007</a> (Judith)<br/><a href="http://www.twitter.com/jonathanmaron" target="_blank">@jonathanmaron</a> (Jonathan)<br/><a href="http://www.twitter.com/mwolffhh" target="_blank">@mwolffhh</a> (Markus)<br/><a href="http://www.twitter.com/awenkhh" target="_blank">@awenkhh</a> (me)</p> <p>The official hashtag is <a href="http://twitter.com/#search?q=%23PHPucEU" target="_blank">#PHPucEU</a>.</p> <p>If you have any questions or are part of a PHP Usergroup in Manchaster, Barcelona, Budapest or Majorca, please get in touch with me &#8212;&gt; andy.wenk@googlemail.com.</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/programming/2010/04/08/phpuceeu-2010-first-meeting http://andywenk.github.io/programming/2010/04/08/phpuceeu-2010-first-meeting 2010-04-08T08:34:48+00:00 Google Chrome extensions <h2>Moin Moin,</h2> <p>recently I stayed at home for two months because my second daughter Naya was born 20th January 2010. Here in Germany we have the possibility to take the so called &#8220;Elternzeit&#8221; which is badly translated as &#8220;parents time&#8221;. It gives you and your partner the chance to take care of the new born. </p> <p>Most of the time I tried do be a good daddy and husband. Means I supported my wife as much as I could and carried Naya around while she was screaming like hell (due to 3 month colics a lot of babys have at the beginning of their life). But there was some time left I used to learn again some programming stuff like digging a little deeper into Rails and hacking JavaScript. Neat.</p> <p>Doing so and due to the fact I am programming web based stuff, I likely use Firefox. But hey there is also that Google Chrome browser you installed few months ago. So why not using this one. And yeah - it&#8217;s really cool. I like the simplicity and reduced UI. But what about extensions? Ok there is the <a href="https://chrome.google.com/extensions" target="_blank">Google Chrome Extensions</a> site I checked. And there are already some cool extensions I use.</p> <h3>Overview about the installed extensions</h3> <p>This is just a short hint. You can find the extensions menu under Window -&gt; Extensions or you click the &#8220;Customize and control Google Chrome&#8221; button (tool icon) in the adress bar and then the entry Extensions in the menu. There is a list with all installed extensions and you are given the ability to change the options, enable or disable and uninstall each extension.</p> <h3>Firebug lite</h3> <p>The one I installed some minutes ago is <a href="https://chrome.google.com/extensions/detail/bmagokdooijbeehmkpknfglimnifench" target="_blank">Firebug lite for Chrome</a>. Actually this version is just a smaller set of the one written for Firefox but hey, it&#8217;s a good start. When developing JavaScript stuff, the most used part is the Console and fortunately it&#8217;s already available. I did not know that this Firebug version is available for Chrome. So a big thank you goes to Markus Wolff (<a href="http://www.twitter.com/mwolffhh" target="_blank">@mwolffhh</a>) who pointed me to this.</p> <h3>goo.gl URL Shortener</h3> <p>Who does not use an URL shortener these day&#8217;s? Sure there are a lot of them available. Having one in your browser bar available is a good thing because you just need to hit it and have the shortened URL for the actual page. I like the <a href="https://chrome.google.com/extensions/detail/iblijlcdoidgdpfknkckljiocdbnlagk" target="_blank">goo.gl Extension</a> a lot but it&#8217;s nothing very special.</p> <h3>Google Reader Notifier</h3> <p>First I was reading the RSS feeds I subscribed to in Mail. But this sucks a little bit, because it&#8217;s a mail client and not an RSS reader. So I started to use Google reader and I am really satisfied. So to quickly open the site and also seeing how many new feeds are available, I installed <a href="https://chrome.google.com/extensions/detail/oaeemlcgfejmkohaddjlhnmaneccmbfb" target="_blank">Google Reader Notifier</a> which is made by Google. This is basically just a link to the Google reader site.</p> <h3>Speed Tracer</h3> <p><a href="https://chrome.google.com/extensions/detail/ognampngfcbddbfemdapefohjiobgbdl" target="_blank">Speed Trace</a>r is also a Google extension. It is useful to examine performance problems. You start recording all the pages you are loading. A lot of important metrics are being tracked. Actually I just used it a couple of times but it seems to be a good tool. To be able to run it under Mac OS X you have to download a litte application called <a href="http://dl.google.com/gwt/speedtracer/ChromeWithSpeedTracer.dmg" target="_blank">Speed Tracer bootstrap application</a>. Running this app will start Chrome with the flag </p><pre>--enable-extension-timeline-api</pre> which is needed to be able to record anything at all. It&#8217;s worth a check I think. You can get further info <a href="http://code.google.com/webtoolkit/speedtracer/get-started.html" target="_blank">here</a>. <h3>Zootool Extension</h3> <p>Last, but definitely not least, there is a wonderful extension available for <a href="http://www.zootool.com" target="_blank"><a href="http://www.zootool.com" target="_blank">www.zootool.com</a></a> which I strongly recommend to check out. Zootool (<a href="http://www.twitter.com/zootool" target="_blank">@zootool</a>) is a web application for storing and managing your bookmarks running in the browser as a website. The cool thing about it is the fact, that it feels like using a desktop application. The extension is opening the save dialog embedded fullscreen in your current window. Really nice! (hey <a href="http://www.twitter.com/bastianallgeier" target="_blank">Bastian</a>, I am still really excited ;-)</p> <h3>While developing</h3> <p>I don&#8217;t want to miss to point you to the developer tools shipped with Chrome. Under View -&gt; Developer in the main menu, you can open the source code of the current page, the Developer Tools and the JavaScript console, and a task manager showing you the ressources used by Chrome. The Developer Tools and the JavaScript console are made in the manner of firebug for Firefox. They are doing a real good job what means, that you can easily use Chrome for developing JavaScript, HTML and CSS.</p> <h3>Conclusion</h3> <p>This was just a small overview about some extensions for Google Chrome. I am using it under Mac OS X. Chrome is a real nice browser and damn fast. The V8 JavaScript engine is doing a good job under the hood. So why not using Chrome?</p> http://andywenk.github.io/www/2010/03/25/google-chrome-extensions http://andywenk.github.io/www/2010/03/25/google-chrome-extensions 2010-03-25T22:00:30+00:00 First HH.js meet up in Hamburg <p>Moin Moin,</p> <p>yesterday, the first HH.js meet up took place in the nice lounge of SinnerSchrader in Hamburg. About 30 JavaScript geeks (some of them called them self newbie) attended and expected a cool first meeting.</p> <p>First of all I wanna say thank you (again ;-) ) to Malte for organizing this and thanks to SinnerSchrader for letting the people use their lounge and supporting the meetup with Pizza and drinks. #awesome!</p> <p>The first topic was <a href="http://nodejs.org" target="_blank">Node</a>. <a href="http://twitter.com/felixge" target="_blank">Felix Geisendörfer</a> was traveling from Berlin to Hamburg to give his talk. Actually he&#8217;s taking part in the project with bugfixing and further development. It&#8217;s a good idea to have look at <a href="http://debuggable.com/posts/javascript-meetup-hamburg-slides:4b8f9986-4e64-4755-b420-074dcbdd56cb" target="_blank">the slides he uploaded at his blog</a>.</p> <p>Node was invented by <a href="http://twitter.com/ryah" target="_blank">Ryan Dahl</a> and is made for serverside JavaScript. It is built on <a href="http://code.google.com/p/v8/" target="_blank">Google&#8217;s Open Source JavaScript engine V8</a> which is in these day&#8217;s the fastest engine available (it does not build binary code but immediately machine code). The big thing is the fact, that Node is providing asynchronous I/O. This is implemented with callback functions and is giving a big advantage compared to other implementations. <a href="http://nodejs.org/#about" target="_blank">Read more about Node and it&#8217;s functionality here</a>.</p> <p>Felix took us on a journey through Node. He explained the way Node works and showed some examples like an simple http or tcp server. It&#8217;s written just in a few lines of code. He also introduced future goals namely the support for <a href="http://en.wikipedia.org/wiki/Web_worker" target="_blank">web workers</a>, readable and writable streams, better socket support and so on. </p> <p>Within the bonus slides he introduced his project Dirty which is basically a mixture of the principle ideas behind <a href="http://couchdb.apache.org/" target="_blank">CouchDB</a> (document based database with a RESTful API) and <a href="http://code.google.com/p/redis/" target="_blank">Redis</a> (an advanced key-value store) to provide a &#8220;scriptable key-value store&#8221;. The sources can be found at <a href="http://github.com/felixge/node-dirty" target="_blank">github</a>. </p> <p>Node is still Alpha and the API is changing a lot without backwards compatibility. It is planned that version 0.2 will be released in between the next 4 - 6 weeks. But Felix mentioned a s a side note, that this goal was set up already half a year ago ;-). When Version 0.2 comes out, a freeze will ensure backwards compatibility for the first time. After that it will be possible to use it in production - for sure at your own risk.</p> <p>So this was really interesting and for sure in many parts kind of &#8220;JavaScript - advanced&#8221;. </p> <p>After a short break and another beer,<a href="http://twitter.com/cramforce" target="_blank"> Malte</a> introduced <a href="http://code.google.com/p/joose-js/" target="_blank">Joose</a>. Joose is a meta object system for JavaScript including classes, inheritance, mixins, traits, method modifiers and other stuff. In his slides, he is taking the idea of M.C. Escher pictures to explain, that Joose is &#8220;programmed in itself (self-hosting)&#8221; and cannot crash. Better said, it works completely or does not work at all. To find out more about metaprogramming, refer to<a href="http://en.wikipedia.org/wiki/Metaprogramming" target="_blank"> this Wiki page</a> - to be honest, I am not able to explain it in depth ;-).</p> <p>After meeting Malte the first time I played around with Joose in some smaller projects. For me coming from OOP in PHP, it was really cool to have the same paradigms in a simple way available in JavaScript. It is helping a lot to develop good structured code. But furthermore there are cool things like before or after methods. Using them in a child class is giving the possibility to do something before or after a method from the parent class is fired. </p> <p>Joose in depth is really powerful and is providing a lot of mechanisms to write really wicked stuff.</p> <p>After Felix and Malte&#8217;s talks, some discussions arose. Basically everybody was kind of &#8220;enlightened&#8221; with the possibility&#8217;s available with JavaScript. One setup could be Node as the server (e.g. http) + Joose for coding + CouchDB as the storage engine. Pure, damn&#8217; JavaScript. A lot of fun &#8230; ;-)</p> <p>While writing this, I found another <a href="http://openjsan.org/doc/s/sa/samuraijack/Joose/3.006/lib/Joose/Manual.html" target="_blank">Joose manual here</a>. It&#8217;s good and you should take a look here also.</p> <p>I am looking forward for the next meet up and hope, that it will take place maybe next month?</p> http://andywenk.github.io/programming/2010/03/04/hhjs-first-meetup-hamburg http://andywenk.github.io/programming/2010/03/04/hhjs-first-meetup-hamburg 2010-03-04T15:18:35+00:00 PostgreSQL UG Germany @ CeBit 2010 <p>EDIT: please read also the <a href="http://andreas.scherbaum.la/blog/archives/675-PostgreSQL-CeBIT-2010.html" target="_blank">blog post by Andreas Scherbaum</a> about the booth at CeBit </p> <p>Moin Moin,</p> <p><a href="http://andreas.scherbaum.la/blog/" target="_blank">Andreas Scherbaum</a>, a well known name in the <a href="http://www.postgresql.org" target="_blank">PostgreSQL community</a>, PostgreSQL expert and consultant from Magdeburg organized a <a href="http://andreas.scherbaum.la/blog/archives/672-Cebit-2010-PostgreSQL-booth-first-impressions.html#extended" target="_blank">booth in the project lounge</a> in between the Open Source area in hall 2 at CeBit. He will be there from 02. - 06.03. - means the whole time <a href="http://www.cebit.de/homepage_e" target="_blank">CeBit</a> is running. </p> <p>He asked some PostgreSQL geeks from Germany to take part as staff. So yesterday it was me, today and tomorrow it&#8217;s Joachim Wieland, Friday it&#8217;s <a href="http://psoos.blogspot.com/search/label/PostgreSQL" target="_blank">Bernd Helmle</a> and Michael Meskes is there 03. or 04.03. PostgreSQL is represented the first time @ CeBit - cool!</p> <p><a href="http://www.postgresql.org" target="_blank"><img src="http://media.tumblr.com/tumblr_kyped5wuUt1qa0m1w.gif"/></a></p> <p>I did not know what to expect. Means, what kind of people are coming to our lill&#8217; booth, what will the questions be and so on. Actually it was quite varying. Some people did already hear about PostgreSQL and were simply interested what PostgreSQL is all about. Others (mostly DBA&#8217;s) had special questions concerning replication and clustering what was a bit more of a challenge to answer - but for sure no problem. And finally also people who want to migrate from MySQL to PostgreSQL did ask some questions. Hopefully we were able to convince them ;-) .</p> <p>The booth it self was really small. Both Andreas and me had our Laptops there where we showed some stuff and in the back some slides were running on a screen. Next to us was <a href="http://wordpress-deutschland.org/" target="_blank">Wordpress</a> placed and in some steps away the guy&#8217;s from <a href="http://www.isc.org/bind10" target="_blank">bind</a> and <a href="http://www.perl.org/" target="_blank">Perl</a> had fun introducing their projects. By the way - thanks again to Carsten for giving me some help installing and setting up bind on my Macbook (what is really simple &#8230; if you know how).</p> <p>It was really fun being there together with Andreas. Actually it was the first time meeting him in real life. I would like to do that again if I can find time. It&#8217;s not only nice to represent a cool OpenSource Project like PostgreSQL but also to meet people from the Open Source scene at all. </p> <p>A big thank you goes out to Andreas for his awesome power and initiative to make this happen. You really rock!</p> <p><img src="http://media.tumblr.com/tumblr_kypdrvIAqj1qa0m1w.jpg"/></p> <p>Last note: before running to my train two guy&#8217;s were asking about <a href="http://couchdb.apache.org" target="_blank">CouchDB</a> and why it is so cool - I gave them a quick introduction &#8230; two new fans now ;-)</p> http://andywenk.github.io/postgresql/2010/03/03/postgresql-pgug-cebit-2010 http://andywenk.github.io/postgresql/2010/03/03/postgresql-pgug-cebit-2010 2010-03-03T11:27:00+00:00 beangie.de and zootool.com <p>Moin Moin,</p> <p>today I just want to point out two real great websites.</p> <h3>beangie.de</h3> <p>I think it&#8217;s now nearly two years since I &#8220;found&#8221; Angela Becker in XING (or did she find me?). Funny as is, I stumbled upon her avatar. She was promted to change this avatar to a real foto by the XING team, but she&#8217;s still using it in twitter (<a href="http://twitter.com/beangie" target="_blank">@beangie</a>). </p> <p>I liked the avatar a lot because it was not the next stupid bourgoise foto of the girl or guy I don&#8217;t want to get in touch with. So I started some smalltalk and we realized, that we&#8217;re both living in Hamburg, like good rock music and have something to do with graphic. </p> <p>As I am not a graphic or web designer, I am always looking for good people in this area. So the stuff she showed me was really cool and thankfully, she started to run her own business as a freelancer. But she had nothing to do with the web. Uh &#8230;. really? I did not care because I thought she can make it also.</p> <p>Well I want to introduce you to her finally launched website where she&#8217;s presenting herself and some work she has done so far. I think it&#8217;s worth a look and maybe you need to get in touch with her because of a project you have. Working with her is totally productive and a lot of fun.</p> <p>Btw. the great programming was done by her friend in love Stefan - follow him at twitter if you like: <a href="http://twitter.com/st_f_n" target="_blank">@st_f_n</a></p> <p><a href="http://www.beangie.de" target="_blank"><a href="http://www.beangie.de" target="_blank">http://www.beangie.de</a></a></p> <img src="http://media.tumblr.com/tumblr_kykuk1TRAL1qa0m1w.png"/><h3>zootool.com</h3> <p>Everybody needs a bookmark app to store bookmarks. Sure you can use <a href="https://addons.mozilla.org/en-US/firefox/addon/10868" target="_blank">Firefox Weave</a> to sync your bookmarks between different machines but I don&#8217;t like it that much (I mean bookmarks in the browser). Or you will use <a href="http://delicious.com/" target="_blank"><a href="http://delicious.com/" target="_blank">http://delicious.com/</a></a> which is approved and well known. The API is also kind of cool because it&#8217;s RESTful in a way. But do you have nice thumbnails of the pages you bookmarked or a nice website with an overview? No!</p> <p>It showed that following Dion Almaer in twitter (<a href="http://twitter.com/dalmaer" target="_blank">@dalmaer</a>)is a good thing because he provided a link to <a href="http://zootool.com" target="_blank">Zootool</a>. Zootool is a web application (yes it really is) written by Bastian Allgeier (<a href="http://www.twitter.com/zootool" target="_blank">@zootool</a>) and is fuckin&#8217; awesome. This was exactly the piece of software I was looking for. It is webbased (what else?), the usability is great, it is looking super cool (like a Mac app ;-) ) and it behaves like a desktop application. </p> <p>Zootool is using MooTools (a cool JavaScript library) heavily to get the desktop app feeling. I will meet Bastian in the middle of March in Mannheim. Maybe he&#8217;s telling me some more about the backend and the programming. And ZooTool is maybe one of the first real browser and webbased applications we can find &#8230;</p> <p>After having some conversation with Bastian (the one like &#8220;ah your app is so super sexy bla bla bla&#8221; - &#8220;oh really thank you bla bla bla&#8221; :-) ) we found out, that he is living 15&#160;km away from the city where my parents still live and I was grown up till I was 24. Aha! That&#8217;s nice ;-). I am talking about Mannheim (Bastian) and Schwetzingen (me) in southern Germany.</p> <p><a href="http://zootool.com/" target="_blank"><a href="http://zootool.com" target="_blank">http://zootool.com</a></a></p> <img src="http://media.tumblr.com/tumblr_kykukkcypl1qa0m1w.png"/><p>Well, I really ask you to have a look to these websites and hope you like them as much as I do &#8230; </p> http://andywenk.github.io/www/2010/03/01/beangie-de-zootool-com http://andywenk.github.io/www/2010/03/01/beangie-de-zootool-com 2010-03-01T00:20:00+00:00 RE: project management in small teams (couch.io) <p>This my answer to a <a href="http://blog.couch.io/" target="_blank">blog post</a> by Jan Lehnardt from <a href="http://couch.io" target="_blank">couch.io</a></p> <p>Hi Jan,</p> <p>kind of funny that you are asking for ideas how to do project management in small teams. We at NMMN were growing from two (Thomas and me) to six people working on our resource management system eUNIQUE. The same question raised and it was me to push this topic in a (hopefully) good direction.</p> <p>I don&#8217;t know much about SCRUM or the principles of agile development in depth but as far as I am concerned, these methods are good. The question is, when are they good or when are they over sized? But an even more important question is, will one be able to start with project management techniques like SCRUM from the very first beginning. In my opinion, a new team or company has to learn the simplest things first and then grow to &#8220;bigger&#8221; solutions &#8230; like SCRUM.</p> <p>What is the homework to be done? First of all it has to be clear what kind of project you have. Let&#8217;s say it&#8217;s a software development project. The questions are:</p> <p># who is in the team?<br/> # who is the team (project) leader?<br/> # who is responsible for the customer communication?<br/> # who is writing the technical specification of the software (in german: Pflichtenheft)?<br/> # who is testing?</p> <p>and so on &#8230;</p> <p>These are some common questions for a project. But before that, you have to work out and write down (kind of a &#8220;project management company policy&#8221;) how you will manage all projects you start. Some questions there are the following (in no order):</p> <p># which version control system will be used?<br/> # where are the repositories placed (network)?<br/> # how is the documentation done and where is it placed (network)?<br/> # how are the tests done and where are the results placed (network)?<br/> # where are all the project documents placed and how is the (folder)structure for each project?</p> <p>and so on &#8230;</p> <p>A very important topic what has to be discussed is furthermore the internal communication. How often are meetings held and where are the results placed (very important: a meeting without a result or without a written report never took place)? What is the rule when communicating with customers (who has to be set to the CC: list and so on)? </p> <p>As you can see, there are a lot of questions in principle. In my opinion these (and more) fundamental questions have to be answered when starting a business and managing projects in teams at the beginning.</p> <p>These short summary or experience is a collection of things we were (and are still) faced when starting different projects in our growing team. The main problem is to set the &#8220;rules&#8221; or &#8220;contracts&#8221; up so that everybody is accepting them. If there is just one person in the team who is kind of &#8220;against it&#8221;, the house is collapsing. </p> <p>And in this concern a real important thing is the need of always following the set up rules. On one hand everybody is used to work in this way and on the other hand, you will save a lot of time when searching for project related documents and so on. The result is a transparent working environment for every project member, for every employee and for the customer.</p> <p>The last thing I want to write here is the fact, that imho the communication with the customer is one of the hardest tasks and should be handled with the biggest care possible. Usually the customer is not speaking techtalk but likes to sound like he is. It is really important to write everything down (as short as possible but as detailed as needed). After some work has been done (parts or the whole software), let the customer test, get feedback, correct stuff, let the customer test again and ask for an ACK (written!). I call this &#8220;feedback loop&#8221; and I am assured that this is the best way to save stress, money and unsatisfied customers.</p> <p>Allready five years ago I was reading a small book by Pascal Mangold called <a href="http://tr.im/Ps1m" target="_blank">"IT Projekt Management kompakt"</a>. Imho this is an awesome small book with extremely good advices how to get your projects done. He is also a fan of eXtreme Programming and agile project management techniques but has also some critical words to say about these techniques. I really recommend reading his book.</p> <p><b>Conclusion</b></p> <p>Doing good project management is not a hard task imho. There are some approved and well known rules of thumb you should follow to create a successful working and project management environment. Important is to start creating this environment at all, learn out of the experience you&#8217;re making and adapt them to correct your rules or policies. Using techniques like SCRUM, waterfall project management, agile development or others is cool but requires to understand them in depth and &#8220;live&#8221; them each time exclusively. If these techniques are adequate for your company or team is a question you have to answer by yourself honestly &#8230; </p> <p>So, hopefully you can get some meat for further thinking, ideas or discussions. Any questions out of these lines - go a head and get in touch with me ;-)</p> <p>Cheers Andy</p> http://andywenk.github.io/work/2010/02/23/project-management-in-small-teams http://andywenk.github.io/work/2010/02/23/project-management-in-small-teams 2010-02-23T13:08:00+00:00 Blog transferred <p>Hi,</p> <p>actually I transferred the posts I wrote in the old blog back to April 2009. These are the posts written in English so I did not transfer the older ones also. You can view the old blog entries (mainly in german so) by following this link:</p> <p><a href="http://blog-old.netzmeister-st-pauli.de" target="_blank">http://blog-old.netzmeister-st-pauli.de</a></p> <p>I have a lot of ideas for new posts here but these days a special girl is asking for my full attention &#8230;</p> <p><img src="http://media.tumblr.com/tumblr_kxydbkEnbh1qa0m1w.jpg"/></p> <p>Kiana and Naya (born 20.01.2010)</p> <p>See, hear or read ya soon ;-)</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/writing/2010/02/16/blog-transferred http://andywenk.github.io/writing/2010/02/16/blog-transferred 2010-02-16T21:08:22+00:00 Stop Software Patents <div align="center"> <a href="http://petition.stopsoftwarepatents.eu/971003512337/" target="_blank"><img src="http://petition.stopsoftwarepatents.eu/banner/971003512337/ssp-300-250.gif" alt="stopsoftwarepatents.eu petition banner" width="300" height="250"/></a> </div> http://andywenk.github.io/www/2010/01/14/stop-software-patents http://andywenk.github.io/www/2010/01/14/stop-software-patents 2010-01-14T10:33:32+00:00 More website performance boosting <h3>Moin,</h3> <p>Kyle Simpson (<a href="http://www.twitter.com/gettify" target="_blank">@gettify</a>) asked me via twitter if I would like to be a BETA tester for his new service <a href="http://www.2static.it" target="_blank">2static.it</a>. For sure I was testing. Actually the private BETA will last for 7 to 14 days.</p> <p>It&#8217;s &#8221; &#8230; a free service for improving the page-load performance of your site by addressing one specific performance detractor &#8212; cookies on static asset requests.&#8221;. If you are using YSLow this is the point &#8220;Use cookie-free domains&#8221;. I was setting this up and it works perfectly. I will post about it later.</p> <p>Watching YSlow giving me better and better grades for my personal website <a href="http://www.nms.de" target="_blank">http://www.nms.de</a>, I thought it would be cool to go further and also make some more adjustments. The next step was to set expire headers. The point in YSlow is &#8220;Add expires headers&#8221;. This is as simple as this:</p> <pre> &lt;FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$"&gt; Header set Expires "Thu, 15 Apr 2020 20:00:00 GMT" &lt;/FilesMatch&gt; </pre> <p>Place this in your apache2.conf or VhostContainer and restart apache. Now apache is setting an expire header for the matched files in the far future. But be careful. You now have to rename the files when you update them. This should not be that difficult. You could add a version number for example.</p> <p>Another issue are ETags. In YSlow this is &#8220;Configure entity tags (ETags)&#8221;. ETags are used for checking out if a ressource in the browsers cache is the same than on the server. If you are not using this meachanisim, the advice is to turn it off - either in your apache conf or in the VhostContainer:</p> <pre> FileETag none </pre> <p>The other rules are more onpage optimization (beside &#8220;Use a Content Delivery Network (CDN)). With a little luck, you will get a B or A grade - yeah ;-)</p> <p>Andy</p> http://andywenk.github.io/server/2010/01/12/more-webiste-performance-boosting http://andywenk.github.io/server/2010/01/12/more-webiste-performance-boosting 2010-01-12T00:14:00+00:00 Compress components in Apache2 (mod_deflate) <p>Moin,</p> <p>actually I am reading Steve Souders book <a href="http://www.amazon.de/High-Performance-Web-Sites-Faster-Loading/dp/0596529309/ref=sr_1_3?ie=UTF8&amp;s=books-intl-de&amp;qid=1263225757&amp;sr=8-3" target="_blank">"High Performance Websites"</a>. He is describing with 14 rules how you can increase the performance of any website. I also saw him live talking <a href="http://jsconf.eu/2009/" target="_blank">@jsconfeu</a> what was really cool ;-) (thanks Steve!).</p> <p>Creating a bigger project like we do with <a href="http://www.e-unique.com" target="_blank">eUNIQUE</a> is kind of a challenge and fun. But seeing it growing and adding a lot of functionality, requires also a lot of maintenance concerning a good usability behavior. The behavior is often defined (or even mostly) in how fast a page is loading.</p> <p>Coming back to Steve Souders and his book, leads to one of the biggest most important rules in achieving a good performance of your website: output compression. This will reduce response times up to 75% - 90%. Wow - awesome! So when trying to set this up in <a href="http://httpd.apache.org/" target="_blank">apache2</a>, I was running in some problems.</p> <p>In apache2, the module which needs to be enabled is called <a href="http://httpd.apache.org/docs/2.2/mod/mod_deflate.html" target="_blank">mod_deflate</a>. For a deeper understanding and further configuration options I recommend reading the docu in depth. To check if the module is enabled you simply fire up this command:</p> <pre> # a2enmod deflate Module deflate already enabled </pre> <p>If you see the result shown above, everything is fine. Otherwise enable it first.</p> <p>Then I was not sure which configuration is need exactly. So here is the most simple way to get compression running, you need the following lines:</p> <pre> SetOutputFilter DEFLATE AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/x-javascript </pre> <p>Uh - what does it mean? First of all we define, that DEFLATE shall be used to compress the output served by the webserver. We then declare which file types have to be compressed. Here we compress all text file types including html, xml, css and javascript (!) files. Actually the compression of css and javascript files was the reason what to look for all this (beacause I had an F grade in YSlow ;-( ).</p> <p>Finally the question was, where to put the directives. If you want to compress all these files for all VirtualHosts you have running, simply put it into your apache2.conf (/etc/apache/apache2.conf). If you want to keep this a little more fine granulated, put it into your VirtualHost container. It doesn&#8217;t matter where you put it there. Although, a good place would be the <directory></directory> or (if you have it) a <location></location> container inside the VirtualHost container.</p> <p>For testing purposes, I am using <a href="http://developer.yahoo.com/yslow/" target="_blank">YSlow as a Firefox Extension</a>. After setting up the directive&#8217;s in apache and doing a graceful reload &#8230; nothing happened. WTF? After playing around for a while I recognized, that I had to clean the Firefox cache and had to stop and start the apache webserver. Doing so, I could see the positive result (getting a A grade for compressing text files ;-) ) in YSlow. Chakka!</p> <p> I think this is a really easy way to increaes the page loading time for your website or project. I strongly encourage you to use it and set it up. Actually I am not sure if you could also use the directives in a .htacces file. Check it out!</p> <p>Andy</p> http://andywenk.github.io/server/2010/01/11/compress-components-apache2-mod-deflate http://andywenk.github.io/server/2010/01/11/compress-components-apache2-mod-deflate 2010-01-11T16:39:00+00:00 ah-yes-its-been-a-while-since-i-wrote-the-last <p>Ah yes, </p> <p>it&#8217;s been a while since I wrote the last post and I planned to write something about the second day @jsconfeu a little sooner. But a lot of work (a lot JS work actually ;-) ) kept me away from doing so. Anyway - here we go.</p> <p>#slides #video<br/><br/> The second day (with not that big hangover as at the first day) started with some Webdesign topics presented by Amy Hoy (@amyhoy). She&#8217;s really a nice guy and &#8220;hanging around&#8221; with the author of <a href="http://script.aculo.us/" target="_blank">script.aculo.us</a> Thomas Fuchs. Basically she was&#8230;</p> http://andywenk.github.io/programming/2009/12/30/ah-yes-its-been-a-while-since-i-wrote-the-last http://andywenk.github.io/programming/2009/12/30/ah-yes-its-been-a-while-since-i-wrote-the-last 2009-12-30T02:20:28+00:00 <p>THIS BLOG WILL MOVE TO </p> <p><a href="http://blog.netzmeister-st-pauli.com" target="_blank"><a href="http://blog.netzmeister-st-pauli.com" target="_blank">http://blog.netzmeister-st-pauli.com</a></a></p> <p>All new posts will be placed there &#8230;</p> <p>I will transfer the best posts from here and then close this (ugly) blog.</p> <p>Cheers</p> <p>Andy</p> <div class="item_footer"><p><small><a href="http://blog.netzmeister-st-pauli.de/index.php/2009/12/30/this-blog-will-move" target="_blank">Original post</a> blogged on <a href="http://blog.netzmeister-st-pauli.de/" target="_blank">Blog Andreas Wenk - Netzmeister St.Pauli Hamburg</a>.</small></p></div> http://andywenk.github.io/writing/2009/12/30/this-blog-will-move-to http://andywenk.github.io/writing/2009/12/30/this-blog-will-move-to 2009-12-30T02:20:27+00:00 Am I still a bad programmer? About testing and refactoring! Moin Moin, <p>in an earlier post (<a href="http://blog.netzmeister-st-pauli.com/post/306975866/testing-php-apps-with-phpunit" target="_blank">PHPUnit - testing PHP apps</a>) I was posting the assumption, that I am a bad programmer. The reasons therefor has been the fact, that I don&#8217;t (unit) test the software I write. Is it still true? &#8230; Kind of!</p> <p>Actually I did some steps in the direction to improve the quality of the code I write. The best thing to do at first is to ask people from whom I think they can help. The topic was &#8220;Testing&#8221;. I was speaking with Arne Blankerts about that and he offered his help during some nice evenings eating Tapas, drinking beer and speaking theoretically about OOP and Testing.</p> <p>The decision was clear on one hand. I have to test my software / my code. On the other side - what does it help if I am the only one who is doing it while working on an app. And how do I convince my co-worker, that we have to test. I knew that it will become a challenge. And now, after some weeks &#8230; I am the only one who is testing. Hey wtf! But step by step.</p> <h3>How testing does not work</h3> <p>I like to make little jokes about Java. And yes I will continue. Not only because of the fact, that other people are making jokes about PHP. I think the programming language is at a minimum responsible for bad written code. It is the pressure to get a project as fast as possible done, the money aspect and finally the hacker who is coding the software. You can write real bad code in PHP - but you can also do that in Java, C, Perl, Ruby, Python and so on. So let&#8217;s go on with making jokes because it&#8217;s just a game and makes the day funny.</p> <p>In our company, we have some guys programming a real cool e-marketing software in Java. Markus Wolf is the team leader and knows a lot about testing. I asked him if he would write some slides for an in house training about testing. Some days later we sat together and he explained the principles about testing. Afterwards we went over to the practical part and &#8216;tried&#8217; to write the first tests for our software eUNIQUE. We are using ZEND Framework and it&#8217;s features - e.g the Registry pattern. Uhu - first mistake because hard to test. So we sat together for about three hours with the result of writing one test for one method. We were (and I am still) using PHPUnit. That&#8217;s testing? Simulating millions of objects (mock objects), including a whole framework, writing many lines to be able to write one $this-&gt;assertEquals(blabla, blub)? C&#8217;mon!</p> <p>So what went wrong? Nothing at all! Really! Because the result, and more important the conclusion of our efforts were simple: the code is written as it is not easily testable. That means - the code is bad! And I am a bad programmer! That was what I was feeling. I had to change that.</p> <h3>First step to be able to test</h3> <p>I don&#8217;t like if others think I am a bad programmer. Would you like that? No! But what is even worse - I don&#8217;t like that I think I am a bad programmer. I had to change that. I had to change this situation not being happy and satisfied with my work. So my decision was to learn how to write better (cleaner) code.</p> <p>When we were having holidays with friends in Denmark, I was reading Martin Fowlers book &#8220;Refactoring&#8221;. This is a real good book. During reading I often thought - yeah - this is the way it should be and man, you did stuff like that already without really knowing, that it is called refactoring. Maybe because of that fact, it was fun to read the book.</p> <p>Beside that book I was reading Kent Becks &#8220;Test Driven Development&#8221; what was good also, but not that what I will be able to do. One aspect not being able to develop in TDD mode is the fact, that learning TDD is a bigger effort than writing Unit Tests after the production code is written (I come to that point later) and that a lot of code I work with is already written. But anyway - the book showed a real good concept and brought a lot of ideas. I will surely read it again.</p> <p>And a third one: Robert C. Martin&#8217;s &#8220;Clean Code&#8221;. This book rocks! Everything you ever wanted to read about how to write a give names to variables, functions, classes, how to write functions and classes, how to comment your code, how to built a system and so on - it&#8217;s in this book. Maybe I like this one most.</p> <p>The essence of these books (and the list is by no means finished) is the following:</p> <i>How do I write code which is clean, well structured and testable?</i> <p>Believe me - it&#8217;s a challange to reach that goal. A lot of experience is needed to be able to say: I can write clean code (the authors of the books have decades of experience). I am in the process of starting to write clean code (to all my future entrepreneur&#8217;s: this is a sign for a good programmer: interest of becoming better and willing to work on it!). And it&#8217;s a lot of fun and gives a lot of secureness.</p> <p>The first step to be able to test code is refactoring. The situation I was speaking of a little before is a good example. The problems in our code are coupling and dependencies. One big target of refactoring is decoupling and less dependencies (if needed you want to use dependency injection). But shall I now write everything new or leave it like it is? Both is wrong! There are some examples in software history that companys died because they thought the only way to get better code is to write everything new. The problem: all the experience, the bugs and their fixes are gone. Writing the software means new bugs and no experience.</p> <p>Leaving the code like it is also a bad idea. So in this situation I like Martin Fowlers view: refactor all the time in little steps. If looking to older code to understand what the code is doing (this is over 70% of what a programmer is doing each day) and if finding stuff which could be written better, do it. The idea is to find a good tradeoff between effort/time for doing it and the things you have been inteded to do when you hit this part of your code. If you have the feeling that it will take too long and it is too complicated to refactor the code part now, don&#8217;t do it right now.</p> <p>More important is what to do with new code. I decided to make a cut. Now if I write code for a specific functionality:</p> <ul><li>I check if the object(s) I created are well designed</li> <li>I check if the methods are doing only one thing and are small enough</li> <li>If not I refactor</li> <li>If the object (or some dependent objects) are finished I write tests for them</li> <li>If tests fail or code (a method) is not testable, I refactor until I can run the test and I have a green bar (or no errors on the shell)</li> </ul><p>It&#8217;s as simple as this. Since I do this, the results are tremendous! I feel much more comfortable because the code is much better readable, easier and at least better.</p> <p>So my conclusion and learning process was to understand, that reliable and good software needs to be unit tested. This is for sure not the only point to reach the target of good software but a fundamental one. I want to encourage every hacker to follow this target and tell im: fuckin&#8217; test your code!</p> (this post is two months old and was not published because I wanted edit it later. After reading it I thought it&#8217;s worth publishing it &#8230;) http://andywenk.github.io/programming/2009/12/30/am-i-a-bad-programmer http://andywenk.github.io/programming/2009/12/30/am-i-a-bad-programmer 2009-12-30T01:16:00+00:00 #jsconfeu - Day 2 <p>Ah yes, </p> <p>it&#8217;s been a while since I wrote the last post and I planned to write something about the second day @jsconfeu a little sooner. But a lot of work (a lot JS work actually ;-) ) kept me away from doing so. Anyway - here we go.</p> <p>#slides #video<br/><br/> The second day (with not that big hangover as at the first day) started with some Webdesign topics presented by Amy Hoy (@amyhoy). She&#8217;s really a nice guy and &#8220;hanging around&#8221; with the author of <a href="http://script.aculo.us/" target="_blank">script.aculo.us</a> Thomas Fuchs. Basically she was talking about good and fancy design and presented some awesome websites.</p> <p><a href="http://www.slideshare.net/shadedecho/loading-javascript-even-a-caveman-can-do-it" target="_blank">#slides</a> #video</p> <p>Next was Kyle Simpson and <a href="http://labjs.com/" target="_blank">LAB.js</a>. LAB.js is a script loader which can be used to load scripts in parallel. Also the JavaScript files or libraries are being preprocessed what means optimized. That is avoiding heavy loading times and therefore increasing the page speed. One main problem is the usage of domready for example in <a href="http://www.jquery.com" target="_blank">jQuery</a> lt 1.3.2 because this is not handabale by LAB.js because of the principle architecture (the same issue is with older <a href="http://www.prototypejs.org" target="_blank">prototype</a> versions). I am using LAB.js in various projects and have really good results.</p> <p><a href="http://www.slideshare.net/javruben/building-realtime-collaborative-apps-with-ajaxorg-platform" target="_blank">#slides</a> #video</p> <p>Then we heard Ruben Daniels and Mike Deboer. These guy&#8217;s presented <a href="http://ajax.org" target="_blank">ajax.org</a> (actually also sponsor of jsconfeu) with a online game like SIMS. Two people can play the game together and seeing, what the other is doing &#8230; yes you&#8217;re right - sounds like Google Wave. I asked Mike what he is thinking about Google Wave. They like it a lot because people now are starting to want stuff like Google Wave. The guy&#8217;s refactored the code now the third time in eight years &#8230; cool!</p> <p>#slides #video</p> <p>jQuery offers a really nice UI (user interface) library. Jörn Zaffer is the main contributor of jQuery UI plugins and showed us, how easy it is to code a web application in less than 45 minutes. I am not using any UI libraries like YUI or also DOJO but it&#8217;s worth to check it out.</p> <p><a href="http://www.slideshare.net/stubbornella/css-wish-list" target="_blank">#slides</a> #video</p> <p>Next was Nicole Sullivan presenting object oriented CSS. Huh? Actually Nicole was speaking about how to really write CSS. She presented a lot of do&#8217;s and don&#8217;t do&#8217;s what was really helpful to bring that into mind again. She has made a approach to make CSS even better and therfor made some suggestions for the CSS Working Group. You can check that out at <a href="http://www.stubbornella.org/content/" target="_blank">here website</a> and at <a href="http://www.slideshare.net/stubbornella/css-wish-list" target="_blank">slide share</a>.</p> <p>#slides <a href="http://jsconf.eu/2009/video_nodejs_by_ryan_dahl.html" target="_blank">#video</a></p> <p>Then the topic was awesome node.js by Ryan Dahl. node.js is used to code serverside javascript applications. It uses the V8 JavaScript engine from Google. Ryan presented an IRC chat completely based on node.js and a big woooohhhhh was going through the crowd. For his awesome work the people honored him with standing ovations. AWESOME!!!!</p> <p><a href="http://www.slideshare.net/tobielangel/unittesting-javascript-with-evidence" target="_blank">#slides</a> #video</p> <p>Tobie Langel is one of the core developers from the prototype JavaScript library. He presented a JavaScript Unit Testing framework called Evidence. He explained the principal mechanisms and usage. Really nice. </p> <p>#slides #video</p> <p>Then Steve Souders from Yahoo and one well known website performance guru held a talk about &#8230; yes &#8230; performance. There are many way&#8217;s of increasing the loading speed of websites. Basically he was complaining a little about big websites like CNN and others, why they need to load over 2 to 3 seconds. He showed also different statistics for different browsers like IE, FF or Chrome. It was very interesting and I think I will buy his books. One thing I will keep in mind is his introduction about the awesomenes of jsconfeu. He said he can&#8217;t remember a conference, where a speaker was receiving standing ovations. In his mind this gesture shows that the crowed is just highly interested, respectful and peaceful with other ideas, people and software. I like that!</p> <p><a href="http://www.slideshare.net/jeresig/testing-performance-analysis-and-jquery-14" target="_blank">#slides</a> #video</p> <p>The last talk was held by John Resig the author of jQuery. He was speaking about unit testing JavaScript. Unfortunately I had to leave the talk because my train back to Hamburg was not waiting for me.</p> <p>jsconfeu in Berlin was super awesome. The people wer super and the speakers with their talks hust awesome. A big thanks goes to Jan, Malte and Holger for their work. I will definitely attend next year.</p> http://andywenk.github.io/programming/2009/12/28/jsconfeu-day-2 http://andywenk.github.io/programming/2009/12/28/jsconfeu-day-2 2009-12-28T23:00:00+00:00 #jsconf - simply awesome! Day 1 <p>It&#8217;s over. What? Ah - an weekend of <i>awesomeness</i>. Actually this word is kind of &#8220;stylish&#8221; among the web-tech-geeks. But obviously it describes the weekend in Berlin simply in the best way. I am talking about the <a href="http://www.jsconf.eu" target="_blank">JSCconf</a> which took place November 07th &amp; 08th this year. Let&#8217;s see what was goin&#8217; on.</p> <p>I was arriving Friday at arround 09:30pm in the Hotel and headed immediately to the pre JSCconf party to a place called Bierkombinat in Kreuzberg (a cool part of Berlin). That place was supposed to have a capazity of, let&#8217;s say 20 people, but around 60 have been there. Awesome. All the conf organizers, namely Jan Lehnardt (CouchDB), Malte Ubl and Holger Blank (both SinnerSchrader Hamburg) hand been there and had been in a real good mood. At this point, a mega big thank you guy&#8217;s for this conference and weekend. Really awesome - again!</p> <p>It was not too hard to get in touch with other geeks. A big hello to Dave &#8216;Furf&#8217; Furfero from New York City (<a href="http://mlb.mlb.com/index.jsp" target="_blank">MLB</a>), Nico Onken (<a href="http://www.dojotoolkit.org/" target="_blank">DOJO</a>) and Tom Hughes-Crocker from San Francisco (<a href="http://developer.yahoo.com/" target="_blank">YAHOO</a>). We ended up at around 03:00am eating a kebab in the wrong place because Furf did not find the place we were supposed to go (a day later and sober, he found out that we should have been walking to the left instead to the right ;-) - well &#8230;). So that was a good beginning.</p> <p>With really to less sleep I attended around 09:30am and a little late to the #jsconf. I&#8217; m gonna give you a brief (more or less) overview of the talks I heard. Actually I will update this blogpost with some URL&#8217;s to slides and videos in the future.</p> <p>The first talk was about <a href="http://www.commonjs.com" target="_blank">commonjs</a> held by Kris Kowal. commonjs is a serverside javascript implementation. It is still under heavy development but really cool.</p> <p><a href="http://www.slideshare.net/kriskowal/commonjs-javascript-everywhere" target="_blank">#slides</a> </p> <p>Francisco Tolmasky then showed <a href="http://cappuccino.org/" target="_blank">cappucino</a>. Man this is definetely totally amazing what the guy&#8217;s at <a href="http://www.280north" target="_blank">280north</a> are doing. cappucino is built with ObjectivJ and brings the desktop to the web. Can you imagine creating your slides (like PowerPoint) online? WTF? It&#8217;s so cool and I strongly encourage you to check it out. Check it out at <a href="http://280slides.com/Editor/" target="_blank">280slides</a>.</p> <p><a href="http://www.slideshare.net/tolmasky/js-conf-2009" target="_blank">#slides</a></p> <p>Afterwards Remy Sharp presented the stuff we will have in <a href="http://remysharp.com/" target="_blank">HTML 5</a>. All the cool new tag&#8217;s like video. A lot of things will be a lot easier in the future. Unfortunately we have to wait a bit since there are still people using beloved IE6 - for sure it does not support HTML5.</p> <p><a href="http://www.slideshare.net/remy.sharp/html5-javascript-apis" target="_blank">#slides</a> <a href="http://jsconf.eu/2009/video_html5_javascript_apis_by.html" target="_blank">#video</a></p> <p>Then we listened to Robert Nyman who gave a brief introduction to JavaScript from scratch. His<br/> clear advice to the audiance was to use JavaScript as JavaScript and not trying to adapt constructs from other languages. He is a big fan of <a href="http://www.json.org" target="_blank">JSON</a>, <a href="http://www.jslint.com/" target="_blank">JSlint</a> and <a href="http://www.crockford.com/javascript/jsmin.html" target="_blank">JSMin</a> - stuff created by Douglas Crockford - the keeper of the <a href="http://en.wikipedia.org/wiki/ECMAScript" target="_blank">ECMAScript</a> jewels ;-). Checkout Robert&#8217;s slides for getting a lot of good info about the JavaScript basics. </p> <p><a href="http://www.slideshare.net/robnyman/javascript-from-birth-to-closure" target="_blank">#slides</a> <a href="http://jsconf.eu/2009/video_javascript_-_from_birth.html" target="_blank">#video</a></p> <p>Nico Onken then introduced us with the <a href="http://www.dojotoolkit.org/" target="_blank">DOJO JavaScript framework</a>. Actually I once used the <a href="http://developer.yahoo.com/yui/" target="_blank">YUI framework</a> but we decided to throw it out of <a href="http://www.e-unique.de" target="_blank">eUNIQUE</a> again because we thought, that the performance was too bad. Unfortunately (shame on me) we did not look deep enough into YUI because there are tools to kind of compress the librarys you are invoking. So because of this (wrong) reason I did not have a look to DOJO. But what I can say is, that it look s really cool and it&#8217;s possible to create amazing stuff with it. One example has to be mentioned: grid!</p> <p><a href="http://www.slideshare.net/nonken/dojo-from-scratch-to-result" target="_blank">#slides</a></p> <p>Now <a href="http://www.couchdb.org" target="_blank">CouchDB</a> and its <a href="http://github.com/couchapp" target="_blank">Couchapp</a>'s. Alex Lang from <a href="http://upstream-berlin.com/" target="_blank">Upstream Berlin</a> (hi ;-) ) was presenting the usage of Couchapp&#8217;s. Couchapp&#8217;s are applications built with CouchDB - and I mean only CouchDB. CouchDB is awesome - I mentioned that in other blogposts a lot. Actually Couchapp&#8217;s offer the possibility to built applications like a blog, a wiki, a twitterclient or stuff like that simply with CouchDB. Super cool! By the way - super cool and fancy were Alex slides. Everything was zooming and spinning (svg) &#8230; woooo &#8230;. ;-)</p> <p>#slides <a href="http://jsconf.eu/2009/video_writing_apps_on_the_edge.html" target="_blank">#video</a></p> <p>Let&#8217;s now come to Malte Ubl&#8217;s presentation about <a href="http://code.google.com/p/joose-js/" target="_blank">JOOSE</a>. He wrote JOOSE (in pure Javascript) to be able to create e.g. classes, mixins or modules like you know it from other OOP Languages like <a href="http://www.smalltalk.org" target="_blank">Smalltalk</a> or <a href="http://www.ruby-lang.org" target="_blank">Ruby</a>. So, it is a meta object system for JavaScript. Actually the idea came from MOOSE what is an object system for PERL to be able to do the same thing. You can do all that inheritance stuff with prototyping in JavaScript but it&#8217;s kind of ugly and annoying. Actually he was telling me that he just wanted to see if it&#8217;s possible to do it in JavaScript and yes it was. At <a href="http://www.sinnerschrader.de/" target="_blank">SinnerSchrader</a> JOOSE is used in big production systems and it&#8217;s obviously running really well. I did check it out all ready and have to say - it&#8217;s cool and fun.</p> <p><a href="http://www.slideshare.net/malteubl/j2ee-joose-a-meta-object-system-for-javascript" target="_blank">#slides</a> <a href="http://jsconf.eu/2009/video_a_meta_object_system_for.html" target="_blank">#video</a></p> <p>Maybe you think this was all ready a lot of cool stuff and my brain is spinning like &#8220;how should I ever check all this out&#8221;. But wait - now we saw Thomas Fuchs. He was writing <a href="http://script.aculo.us/" target="_blank">script.aculo.us</a> (really - this name sucks because I can&#8217;t remember it &#8230; ;-) ). He was speaking about JavaScript Performance and was presenting a lot of &#8220;no go&#8217;s&#8221; in JavaScript. He was testing really a lot and brought the results for the different browsers to the audience. If you want to learn more about his (and Amy Hoy&#8217;s) ideas check out the website <a href="http://javascriptrocks.com/performance/" target="_blank">JavaScript Rocks</a>! </p> <p>#slides <a href="http://jsconf.eu/2009/video_extreme_js_performance_b.html" target="_blank">#video</a></p> <p>Well the last talk for this day was held by Douglas Crockford. I think everybody know&#8217;s who he is and so he was welcomed like a Rock Star (I think he is kind of in the JavaScript world ;-) ). He was speaking about his work at the ECMAScript committee, what his goal is and which problems occur (for example the blockade from IBM). This was not really related to hacking JavaScript but really interesting because the standardization and development of ECMAScript (JavaScript) is super interesting for all people coding JavaScript.</p> <p>#slides <a href="http://jsconf.eu/2009/video_state_and_future_of_java.html" target="_blank">#video</a></p> <p>So this was day 1. After all the talks we were going back to the hotel to get a nap. At around 09:45pm Furf, Kyle Simpson, his wife and me went to the JSConf party. Really a cool place, good finger food, free drinks (yeah!), a lot of geeks and shitty music (in my opinion for sure ;-) - it&#8217;s all about taste you know). Hopefully I will find some time soon to write about the talks at the second day.</p> <p>I hope JSConf will be held next year in Berlin again. Actually I am thinking about attending JSConf in Washington DC April next year. Let&#8217;s see &#8230;</p> http://andywenk.github.io/programming/2009/11/09/jsconfeu-day-1 http://andywenk.github.io/programming/2009/11/09/jsconfeu-day-1 2009-11-09T23:00:00+00:00 moin-moin-after-taking-part-at-the-php <p>Moin Moin,</p> <p>after taking part at the <a href="http://www.php-unconference.de/" target="_blank">PHP Unconference</a> this year in Hamburg and having a great time there, <a href="http://www.andresen.de" target="_blank">Judith Andresen</a> had the idea to initialize a <a href="http://www.intphpunconf.org/" target="_blank">International PHP Unconference</a>. I think this idea is just great. Not only german speaking PHP enthusiasts (and also people from other IT related areas), but also english speaking people will have the opportunity to attend to a real cool conference. The benefits are clear in my opinion:</p> <p>- affordable costs<br/> - due to the self structured and&#8230;</p> http://andywenk.github.io/programming/2009/09/28/moin-moin-after-taking-part-at-the-php http://andywenk.github.io/programming/2009/09/28/moin-moin-after-taking-part-at-the-php 2009-09-28T13:44:29+00:00 hi-you-can-see-my-beloved-daughter-kiana-she Hi, … you can see my beloved daughter Kiana. She is waiting for her sister to be born January 2010 and knows that she has got a proud mommy and daddy … Andy http://andywenk.github.io/family/2009/09/25/hi-you-can-see-my-beloved-daughter-kiana-she http://andywenk.github.io/family/2009/09/25/hi-you-can-see-my-beloved-daughter-kiana-she 2009-09-25T11:09:00+00:00 PHP Magazin - PostgreSQL 8.4 und LDAP <p>Moin Moin,</p> <p>ab sofort ist das neue PHP Magazin am Kiosk erhältlich. Dieses Mal habe ich einen Artikel zu den neuen Features der PostgreSQL 8.4 geschrieben. Darin geht es um allgemeine Neuerungen, Window Functions, CTE (Common Table Expressions) und einige weitere Dinge. Go and get it ;-)</p> <p>Ausserdem kann hier der Artikel über PHP und LDAP von Thomas Pfeiffer und mir heruntergeladen werden. Der Artikel war in der Ausgabe 02.09:</p> <p><a href="http://blog.netzmeister-st-pauli.de/media/blogs/andreas-wenk/PDF/PHP_Magazin_2.09_LDAP_pfeiffer_wenk2.pdf" title="" target="_blank">PHP Magazin 02.09 LDAP Artikel</a> </p> <p>Ja das ist schon ein wenig her, aber leider haben wir vergessen das PDF anzufordern. Jetzt also voller Lesespass garantiert.</p> http://andywenk.github.io/programming/2009/09/17/php-magazin-postgresql-ldap http://andywenk.github.io/programming/2009/09/17/php-magazin-postgresql-ldap 2009-09-17T22:00:00+00:00 talks @ phpunconference Moin Moin, <p>cool - <a href="http://www.php-unconference.de" target="_blank">PHP Unconference</a> is really good this year (again good). I&#8217;ve got the feeling, that the quality and the level of the held talks have grown compared to last year. Here is a short summary of what I heard. </p> <h3>Day 1</h3> <p> <strong># memcache / <a href="http://blog.nevalon.de/" target="_blank">Gordon Franke</a></strong> </p> <p> <a href="http://de2.php.net/memcache" target="_blank">memcache</a> is RAM based and easy accesible storage system. The talk showed opportunities to use it with PHP. For example it&#8217;s easy to set the session.save_handler to memcache. The performance boost is amazing: ten times faster then using the filesystem. </p> <p> <strong># Netbeans for developer / Ingo Reinhart and Bastian Feder (<a href="https://twitter.com/lapistano" target="_blank">@lapistano</a>)</strong> </p><p> <a href="http://netbeans.org/downloads/" target="_blank">Netbeans</a> vs. <a href="http://www.eclipse.org" target="_blank">Eclipse</a> with PDT. Who&#8217;s the winner? For me surely Netbeans. Since I am using Netbeans I don&#8217;t want to bash my monitor or - better - the whole working station because of never ending waiting and Nullpointer Exceptions in Eclipse (sorry to all Eclipse guy&#8217;s ;-) ). </p> <p> Ingo showed us how to use Netbeans. Ok - quite clear. After the session I asked him some stuff about integreating <a href="http://www.xdebug.org/" target="_blank">xdebug</a> and debugging. Very easy and a good choice. At home I was also integrating UnitTests with Netbeans. Assumed that <a href="http://www.phpunit.de/" target="_blank">PHPUnit</a> is installed, Netbeans is generating a skeleton for your tests. Very cool! </p> <p>Slides: <a href="http://www.slideshare.net/IngoReinhart/netbeans-fr-phpentwickler" target="_blank"><a href="http://www.slideshare.net/IngoReinhart/netbeans-fr-phpentwickler" target="_blank">http://www.slideshare.net/IngoReinhart/netbeans-fr-phpentwickler</a></a> </p> <p> <strong># PHPillow - <a href="http://kore-nordmann.de" target="_blank">Kore Nordman</a></strong></p> <p> Yeah - there we go again. <a href="http://couchdb.apache.org" target="_blank">CouchDB</a> is cool and <a href="http://kore-nordmann.de/blog/phpillow_php_couchdb_wrapper.html" target="_blank">PHPillow</a> is a wrapper for PHP to talk to CouchDB. Kore was talking a lot about how to get data out of CouchDB what is made by creating map and reduce functions. Basically and originally these functions are written in JavaScript but can be written in actually every Language. A brilliant talk with brilliant slides. </p> <p> Slides: <a href="http://kore-nordmann.de/portfolio.html" target="_blank"><a href="http://kore-nordmann.de/portfolio.html" target="_blank">http://kore-nordmann.de/portfolio.html</a></a> </p> <p> <strong># Refactoring - Unit Testing / <a href="http://stubbles.org/" target="_blank">Frank Kleine</a> &amp; Thorsten Rinne</strong> </p> <p> As I mentioned in earlier posts, the need for testing is now burned in my head. And I like it. Frank and Thorsten were talking about how to write code that it is possible to test it at all. The main killers are Singletons and Registry Patterns. So the advice is clear: DON&#8217;T DO IT! </p> <p> Slides: <a href="http://www.stubbles.org/exit.php?url_id=422&amp;entry_id=66" target="_blank"><a href="http://www.stubbles.org/exit.php?url_id=422&amp;entry_id=66" target="_blank">http://www.stubbles.org/exit.php?url_id=422&amp;entry_id=66</a></a> </p> <h3>Day 2</h3> <p> <strong># Semantic Web - <a href="http://kore-nordmann.de" target="_blank">Kore Nordman</a></strong> </p> <p> Uh - the topic is not really speaking for it self if you don&#8217;t know what &#8220;semantic&#8221; means. But everybody is using it in a way - even if you don&#8217;t know that you use it. There are different semantics like RDF, RDFa, RDF-Schema, Microformats, OWL, SPARQL (SQL for RDF). Kore explained the way to use these semantics and where the problems can be found. The target is to get more info into HTML so that it is possible to e.g. search for &#8220;All citys of South Africa&#8221;. </p> <p> The main problem is actually, that the browser&#8217;s do not integrate the tags in standard, so we destroy valid HTML. Let&#8217;S see what the future brings. </p> <p> Slides: <a href="http://kore-nordmann.de/portfolio.html" target="_blank"><a href="http://kore-nordmann.de/portfolio.html" target="_blank">http://kore-nordmann.de/portfolio.html</a></a> </p> <p> <strong># MVC - <a href="http://www.priebsch.de/" target="_blank">Stefan Priebsch</a></strong> </p> <p> Nearly nobody is using MVC correctly in web apps. Even the best known frameworks don&#8217;t. The talk was more or les a discussion about using MVC in web apps. Really interesting and my personal point of view was approved again. We don&#8217;t want big frameworks lik ZF - we are artists and write our stuff by ourself (you need not more than one day for a MVC skeleton). </p> <p> Actually I did not hear the last two slots because of lack of interest. I sat together with Arne, Stefan and Sebastian (<a href="http://thephp.cc/" target="_blank">thePHP.cc</a>) and had a good talk about some stuff relating Stefan and Sebastians upcoming book about QA and about code sniffer and the newly written PHP QA by Stefan. PHP QA is a new (and better) code analyzer in development. </p> <p> That was good and fun. Thanks for all the talks in talks or in the lobby! </p> <p> By the way - see the <a href="http://wiki.php-unconference.de" target="_blank">PHP Unconference Wiki </a>for info about all talks (click timetabel saturday and timetable sunday)</p> http://andywenk.github.io/programming/2009/09/12/talks-at-phpunconference http://andywenk.github.io/programming/2009/09/12/talks-at-phpunconference 2009-09-12T22:00:00+00:00 phpunconference 12/13 September 2009 <p>Moin Moin,</p> <p>after two weeks holiday and nearly totally offline I found myself back in the office to setup my new MAC Mini. Yeah! I must say - MAC OS X is definitely the best OS I ever used. Even if there&#8217;s not really a need for, one of the first software I installed was <a href="http://www.parallels.com/products/desktop/" target="_blank">Parallels</a> to have a <a href="http://www.debian.org" target="_blank">Debian Linux</a> available. For me, this is actually the perfect working place. Just imagine how much software and tools you have in one really small machine. This is really inspiring and helpful to make a good job each day.</p> <p>But now some words to the topic of this post. I will attend at this years <a href="http://www.php-unconference.de/" target="_blank">PHP Unconference</a> here in Hamburg Rock City. The PHP Unconference will be held in the &#8220;Geomatikum&#8221; at Bundesstraße 55. It&#8217;s part of the University of Hamburg. Over 200 visitors are registered and a lot of cool topics will be discussed. </p> <p>The idea behind the Unconference is quite charming because &#8220;Un&#8221; means &#8220;self organized&#8221;. This means the schedule will be established during the introduction at Saturday. Everybody will get an amount of &#8220;points&#8221; which he can use to vote for the talks submitted by the attendees. This year it&#8217;s also possible to <a href="http://contrib.php-unconference.de" target="_blank">contribute a topic</a> (or more) at the website. There, it&#8217;s also possible to vote for a topic in advance of the conference.</p> <p>My contribution is a talk about the fulltext search of the PostgreSQL. Actually there are not that big amount of votes yet (exactly two ;-) - one is mine, but don&#8217;t tell anyone). But hey, how sould I compete against excellent Kore Nordmanns talk about PHPillow or Sebastian Bergmanns talks about scalability of PHP and PHPUnit or Arne Blankerts talk about security in PHP (yes for sure I will attend to these talks and I am really looking forward ;-) ).</p> <p>The topics of my talk are:</p> <p>- how does full text search work in PostgreSQL<br/> - which dictionary&#8217;s are available and how do you create them<br/> - configuring the full text search<br/> - which functions are available for the full text search<br/> - how to index data (by hand, with a user defined function, with trigger procedures)<br/> - how to create a search query</p> <p>I will show this in psql and with a small PHP application. Well - I hope that I have enough time till Saturday to create the slides and the small app ;-).</p> <p>See you Saturday or Sunday?</p> http://andywenk.github.io/programming/2009/09/07/php-unconference-12-13-september-2009 http://andywenk.github.io/programming/2009/09/07/php-unconference-12-13-september-2009 2009-09-07T22:00:00+00:00 Boosting eUNIQUE - PostgreSQL 8.3 <p>Moin Moin,</p> <p>today we finally switched <a href="http://www.e-unique.com" target="_blank">eUNIQUE</a> over from <a href="http://www.postgresql.org" target="_blank">PostgreSQL</a> 8.1 to 8.3. The reason for waiting that long was the hope to finde time to port the implementation of the contrib module tsearch2 to the integrated fulltextsearch (based on tsearch2) of PG 8.3. Even though we did not find the time, we switched.</p> <p>The process was fairly simple because the onboard programs pg_dump and pg_restore are making the PostgreSQL admin&#8217;s life easy. So we dropped a note to our customers, that the upgrade will take aprox. one hour. Dumping the databases and restoring them took us about 15 minutes - and there have even been some smaller issues so that we had to drop a database and create it again.</p> <p>Because there was some time left (wow - 45 minutes ;-) ) we decided to check the configuration of our PostgreSQL cluster. Actually we realized, that we had been lousy dbadmins because the configuration (postgresql.conf) was not optimized for the underlying machine (Intel Xeon CPU X3210&#160;2.13GHz, 8&#160;GB ram). </p> <p>To enable the PostgreSQL to use higher values, it is needed to raise the shared memory settings in the kernel. So you have to rais the following values:</p> <p>kernel.shmmax = 2147483648<br/> kernel.shmall = 2147483648</p> <p>Human readable: 2GB.</p> <p>Now you are able to raise the following values (not all depend on higher settings for shared memory for sure) in postgresql.conf:</p> <p># to make VACUUM happy:<br/> maintenance_work_mem = 480MB </p> <p># raised form 0.5 to 0.7 to give the process mor time<br/> checkpoint_completion_target = 0.7&#160;</p> <p># this is set from 3 to 8 what means there are 128&#160;MB transactionlog befor <br/> # firering a checkpoint<br/> checkpoint_segments = 8&#160;</p> <p># let PG use a lot of RAM for querys so that there is no need to use the hd <br/> effective_cache_size = 5632MB </p> <p># let PG use a lot of RAM for sorting, joins and scans<br/> work_mem = 40MB </p> <p># enough needed for big transactions <br/> wal_buffers = 4MB </p> <p># how much is used by PG - this is raised a lot because of the 8&#160;GB RAM<br/> shared_buffers = 1920MB </p> <p># raised from 100 to 200 - we have a quite good machine ;-)<br/> max_connections = 200&#160;</p> <p>Be sure to backup your postgresql.conf first. The values are based on the values proposed by <a href="http://pgfoundry.org/projects/pgtune/" target="_blank">pgtune</a>.</p> <p>After restarting the cluster and checking the application we recognized a really fast and good behaviour (much better than before). We had the feeling that Apache is now the bad guy when a page needs to load a little ;-)</p> <p>Happy we are!</p> http://andywenk.github.io/postgresql/2009/08/16/boosting-eunique-postgresql-8-3 http://andywenk.github.io/postgresql/2009/08/16/boosting-eunique-postgresql-8-3 2009-08-16T22:00:00+00:00 JSConf.eu in Berlin 7. and 8. November 2009 <p>Moin Moin,</p> <p>the web&#8217;s dynamic clientside language is JavaScript. Everybody knows, that it had kind of a ressurection with the emerging buzzweb 2.0. There are cool librarys and frameworks like <a href="http://prototypejs.org/" target="_blank">prototype</a>, <a href="http://jquery.com/" target="_blank">jquery</a>, <a href="http://www.dojotoolkit.org/" target="_blank">dojo</a> and so on and applications using JavaScript heavily like <a href="http://couchdb.apache.org" target="_blank">CouchDB</a> (using jquery). So what could be better to attend at a high class JavaScript conference - and even better - in Berlin / Germany. </p> <p>If you are a JavaScript geek or want your head filled with ideas and techniques of some of the top JavaScript people out there, go and register for <a href="http://jsconf.eu" target="_blank">JSConf.eu</a>. The European JavaScript Conference will be held 7th &amp; 8th November 2009 in Berlin. You will get all info at their <a href="http://jsconf.eu" target="_blank">website</a>. </p> <p>I think this will be a real top event. Some of the speakers are allready mentioned: <a href="http://ejohn.org/" target="_blank">John Resig</a> (creator of jquery), <a href="http://mir.aculo.us/" target="_blank">Thomas Fuchs</a> (creator of script.aculo.us), <a href="http://almaer.com/blog/" target="_blank">Dion Almaer</a> &amp; <a href="http://benzilla.galbraiths.org/" target="_blank">Ben Galbraith</a> (Mozilla) just to mention some &#8230;</p> <p>The event is organized by <a href="http://jan.prima.de/" target="_blank">Jan Lehnardt</a>, Berlin @janl, <a href="http://www.xing.com/profile/Holger_Blank" target="_blank">Holger Blank</a>, Hamburg @hblank, <a href="http://www.nonblocking.io/" target="_blank">Malte Ubl</a>, Hamburg @cramforce. Thank you guy&#8217;s!</p> <p>See you there?</p> <p>Andy</p> http://andywenk.github.io/programming/2009/08/12/jsconfeu-berlin-2009 http://andywenk.github.io/programming/2009/08/12/jsconfeu-berlin-2009 2009-08-12T22:00:00+00:00 Is it cool to write a recension for an author as an author <p>Moin Moin,</p> <p>actually I was thinking about the question if it is cool to write a recension about a book from an author as an author. The question came up because one of my favorite PostgreSQL books is the one written by <a href="http://petereisentraut.blogspot.com/" target="_blank">Peter Eisentraut</a> and Bernd Helmle - &#8220;PostgreSQL Administration&#8221; (german). So now I think - why the fuck not? I don&#8217;t wanna have to think about &#8220;uh - is this ok, and what do the people think about if they recognize, that I am also writing a book about PostgreSQL&#8221;. Or even better: &#8220;maybe people think this is kind of guerilla martketing bla bla bla&#8221;. This is bullshit. </p> <p>In these days everything is open and everything is growing and everybody knows everybody and everything is peaceful. The driving force is the idea of OpneSource or services like Twitter. There is no reason in my opinion to not support other people with their work. Quite the contrary is true - I have to support them because I am parttaking in their work. If there are customer or book reader / buyer who think this is not ok they can go and buy some other stuff.</p> <p>So here is the recension (german only - sorry) I wrote at <a href="http://www.amazon.de/gp/product/3897217775/ref=cm_cr_rev_prod_img" target="_blank"><a href="http://www.amazon.de" target="_blank">www.amazon.de</a></a>:</p> <p>"Die PostgreSQL Datenbank ist nicht mehr die "Entwickler Datenbank" die man zum Laufen bekommt, wenn man ein Studium als DBA absolviert hat. Nicht zu letzt deswegen, weil Leute wie Peter Eisentraut und Bernd Helmle sich die Mühe machen, Bücher wie das vorliegende zu schreiben.</p> <p>Die Weiterentwicklung bzw. der Release Zyklus der PostgreSQL hat einen Turnus von ca. einem Jahr. Dabei werden von Version zu Version neben neuen features immer wieder Verbesserungen in vielen Bereichen vorgenommen. So auch die Bedienung und Konfiguration eines Datenbankclusters.</p> <p>Das Buch behandelt die Version 8.3, beschreibt aber generell die Konzepte für die unterschiedlichen features der PostgreSQL. Dadurch ist eine Abwärtskompatibilität für ältere Versionen aus der 8.x Reihe gegeben.</p> <p>Gerichtet ist das Buch an jeden, der die PostgreSQL professionell einsetzen möchte und die Konzepte verstehen will. Ob das ein reiner DBA oder ein Entwickler von Datenbank gestützter Software ist, spielt keine Rolle. Im Buch werden alle Bereiche der PostgreSQL Administration nachhaltig und mit vielen Beispielen erklärt. Das reicht von der Installation, Benutzerverwaltung, Monitoring, Backup und Recovery, Performance Tuning bis hin zum Einsatz von Connection Pools (pgpool-II, pgBouncer) und Replikation (WAL Replikation, Slony-I).</p> <p>Ich kann das Buch jedem ans Herz legen, der sich mit der PostgreSQL beschäftigt. Die online Dokumentation der PostgreSQL ist mit Sicherheit die Informationsquelle der ersten Wahl für alle Benutzer der PostgreSQL. Allerdings geht das Buch weiter und mehr in die Tiefe und ist auf deutsche geschrieben. Letzterer Punkt kann doch für den einen oder anderen Anwender eine kleine Hürde darstellen.&#8221;</p> <p>If you like it - buy Peter&#8217;s and Bernd&#8217;s book ;-). </p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/postgresql/2009/08/10/is-it-cool-to-write-a-recension-about-another-aouthor http://andywenk.github.io/postgresql/2009/08/10/is-it-cool-to-write-a-recension-about-another-aouthor 2009-08-10T22:00:00+00:00 CouchDB jsconf 2009 <p>Moin Moin,</p> <p>I just received a retweet from Jan Lehnardt including a link to a CouchDB video filmed at the JSCONF in April 2009. The actors are Chris Anderson and Jan Lehnardt talking about CouchDB. If you wanna have an idea what CouchDB is all about just go ahead an see this really good presentation:</p> <p><a href="http://jsconf2009.com/couch_video.html" target="_blank"><a href="http://jsconf2009.com/couch_video.html" target="_blank">http://jsconf2009.com/couch_video.html</a></a></p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/couchdb/2009/08/05/couchdb-jsconf-2009 http://andywenk.github.io/couchdb/2009/08/05/couchdb-jsconf-2009 2009-08-05T22:00:00+00:00 PostgreSQL article in german PHP Magazin <p>Moin Moin,</p> <p>one hour ago I sent an article called <strong>"Out Now! PostgreSQL 8.4"</strong> for the next issue of the german <a href="http://it-republik.de/php/" target="_blank">PHP Magazin</a>. I am writing about the changes and new features of the PostgreSQL 8.4 including window functions, cte&#8217;s, recursiv query&#8217;s, psql improvements and some other related stuff.</p> <p>The magazin has the number 6.09 and will be available in September this year, I will leave a note then.</p> <p>Cheers</p> <p>Andy</p> http://andywenk.github.io/postgresql/2009/08/02/postgresql-article-in-german-php-magazin http://andywenk.github.io/postgresql/2009/08/02/postgresql-article-in-german-php-magazin 2009-08-02T22:00:00+00:00 Git Community Book <p>Moin Moin,</p> <p>yeah I know there are a lot of ressources concerning git. Actually I think I found the one I like most. </p> <p><a href="http://book.git-scm.com" target="_blank"><a href="http://book.git-scm.com" target="_blank">http://book.git-scm.com</a></a></p> <p>You can find several documentation types there. Most interesting for starters will be <a href="http://book.git-scm.com/1_welcome_to_git.html" target="_blank"><a href="http://book.git-scm.com/1_welcome_to_git.html" target="_blank">http://book.git-scm.com/1_welcome_to_git.html</a></a>. This is a nice introduction to git looking at all aspects needed for the daily work with git. Nice is the fact, that you can read it step by step with an increasing level.</p> <p>Actually I am really thinking of changing from svn to git for <a href="http://www.e-unique.com" target="_blank"> eUNIQUE</a>. git is really cool and the functionality is more advanced than in svn.</p> <p>Cheers</p> <p>Andy</p> <p>[Edit:] Please check also this: <a href="http://progit.org" target="_blank"><a href="http://progit.org" target="_blank">http://progit.org</a></a></p> http://andywenk.github.io/server/2009/07/21/git-community-book http://andywenk.github.io/server/2009/07/21/git-community-book 2009-07-21T22:00:00+00:00 PostgreSQL Praxisbuch - Fortschritt Moin Moin, mal wieder auf deutsch da es um&#8217;s Buch geht und das nur auf deustch erhältlich sein wird. In den letzten Wochen habe ich fast jeden Abend am PostgreSQL Buch geschrieben. Der geplante Abgabetermin für das Manuskript war der 15.07. Allerdings ist klar geworden, dass das nicht realisierbar ist. Nach einem sehr guten Gespräch mit unserem Lektor Jan Waterman vom Galileo Computing Verlag haben wir jetzt den 20.08. als endgültigen Abgabetermin festgelegt. Wenn alles gut geht, erscheint das Buch dann Anfang September. Gerade habe ich das Kapitel über Performance Tuning beendet. Davor war ich bei der Volltextsuche. Das Schreiben macht extrem viel Spass. Denn zum einen durchwühle ich das Web nach PostgreSQL (wobei sehr gut aussortiert werden muss) und kenne die Doku bald auswendig ;-) . Dazu kommt noch, dass ich auch auf den Mailinglist&#8217;s wieder aktiver bin um Fragen zu beantworten. Allerdings ist das nicht mit Tom Lane vergleichbar. Ich hab&#8217; das Gefühl er beantwortet (in extrem hoher Qualität) so ziemlich jeden post. Schlußendlich kommt das Projekt Buch sehr gut voran und wir können &#8220;das Meer schon sehen&#8221;. Ein Vorgeschmack auf das cover schonmal hier: <p><img src="http://media.tumblr.com/tumblr_kxyaqq1WzK1qa0m1w.jpg"/></p> Und hier noch der Link zur <a href="http://www.galileocomputing.de/katalog/buecher/titel/gp/titelID-2008?GalileoSession=17114777A4F-a9.LYUs" target="_blank">Buchseite</a> beim Galileo Computing Verlag. Andy http://andywenk.github.io/postgresql/2009/07/18/postgresql-praxisbuch-fortschritt http://andywenk.github.io/postgresql/2009/07/18/postgresql-praxisbuch-fortschritt 2009-07-18T22:00:00+00:00 MVCC in PostgreSQL <p>Moin Moin,</p> <p>actually I received a tweet to a blog post from J. Chris Anderson (CouchDB developer) with title &#8220;Fixing HTML 5 Storage&#8221;. He is writing about the approaches of implementing a local storage feature to HTML 5 (<a href="http://dev.w3.org/html5/webstorage/#the-storage-interface" target="_blank"><a href="http://dev.w3.org/html5/webstorage/#the-storage-interface" target="_blank">http://dev.w3.org/html5/webstorage/#the-storage-interface</a></a>). Please read his very interesting post at <a href="http://jchrisa.net/drl/_design/sofa/_show/post/Fixing-HTML-5-Storage" target="_blank"><a href="http://jchrisa.net/drl/_design/sofa/_show/post/Fixing-HTML-5-Storage" target="_blank">http://jchrisa.net/drl/_design/sofa/_show/post/Fixing-HTML-5-Storage</a></a>.</p> <p>He was talking about which the best way would be to implement this feature and is concerned about having no locks while storing or reading data. That means that a multi version concurrency control (MVCC) should be implemented (like also in CouchDB). </p> <p>MVCC was originally introduced by PostgreSQL (edit: apparently by InterBase - thanx to andreas) and this is a really big advantage compared to database systems with out it. There is a very good article written by Joseph Mitchell about how MVCC is working in PostgreSQL. The article was written 2001 but is still up to dat. I ask you to read it under <a href="http://onlamp.com/pub/a/onlamp/2001/05/25/postgresql_mvcc.html?page=last&amp;x-maxdepth=0" target="_blank"><a href="http://onlamp.com/pub/a/onlamp/2001/05/25/postgresql_mvcc.html?page=last&amp;x-maxdepth=0" target="_blank">http://onlamp.com/pub/a/onlamp/2001/05/25/postgresql_mvcc.html?page=last&amp;x-maxdepth=0</a></a> to get an idea what MVCC in PostgreSQL is.</p> <p>More about MVCC can also be read in the offical PostgreSQL docu under <a href="http://www.postgresql.org/docs/8.4/interactive/mvcc-intro.html" target="_blank"><a href="http://www.postgresql.org/docs/8.4/interactive/mvcc-intro.html" target="_blank">http://www.postgresql.org/docs/8.4/interactive/mvcc-intro.html</a></a></p> <p>Andy</p> http://andywenk.github.io/postgresql/2009/07/14/mvcc-postgresql http://andywenk.github.io/postgresql/2009/07/14/mvcc-postgresql 2009-07-14T22:00:00+00:00 Database Modeling Tools <p>Hi,</p> <p>actually a user was looking for a database modeling tool at the <a href="http://www.postgresql.org/community/lists/" target="_blank">postgresql mailinglist</a>. As I do use a piece of paper for my db modeling and having used <a href="http://fabforce.net/dbdesigner4/" target="_blank">DbDesigner</a> during my time using MySQL and Windows, I thought it would be a good chance to have a look at some tools. Actually two have been supposed by the list members.</p> <p><strong>Power* Architect (thanks to Thomas Kellerer for the tip)</strong></p> <p>This is a data modeling and profiling tool. It supports not just PostgreSQL but also many other DBMS. The connection to the database is handled by a JDBC driver. It&#8217;s avilable for MAC OS X, Windows and Linux and it&#8217;s open source (GPL v 3). <br/> Here are some more features (copied from the page below):</p> <p>- Connects to multiple source databases concurrently<br/> - Compares data models &amp; database structures and identifies discrepancies<br/> - Drag-and-drop source tables &amp; columns into the playpen<br/> - Remembers the origin of each column<br/> - Generates source-to-target visual Mapping Reports<br/> - Forward-engineers to PostgreSQL, Oracle, MS SQL Server &amp; more<br/> - Saves source data structure snapshots in the project, so you can work remotely<br/> - All project data is stored in an easy-to-parse XML format<br/> - OLAP schema modeling: Cubes, Measures, Dimensions, Hierarchies &amp; Levels</p> <p>Power* Architect is developed by a Canadian company called SQL Power. You can get more info and download at <a href="http://www.sqlpower.ca/page/architect" target="_blank"><a href="http://www.sqlpower.ca/page/architect" target="_blank">http://www.sqlpower.ca/page/architect</a></a></p> <p><strong>MicroOLAP Database Designer for PostgreSQL (thanks to Pavel Golub for the tip)</strong></p> <p>This is another one but unfortunately available only for Windows. As of this reason, I did not check it but it is said, that it has a good support for <a href="http://www.winehq.org/" target="_blank">wine on Linux</a> OS. Here are some features (taken from the page below):</p> <p>-simple physical database creation by using a wizard;<br/> -Database structure generation;<br/> -Database modification: generation of ALTER statements to bring a database to the state of the diagram;<br/> -Reverse engineering (import) of existing databases from multiple sources;<br/> -Export of a diagram to popular graphics formats;<br/> -Database structure reports generation;<br/> -Cheking a diagram for errors;<br/> -Merging of diagrams;<br/> -Ability to print diagram out on multiple pages;<br/> -Works under Windows 2000, XP, 2003.<br/> -Support of PostgreSQL server starting from 7.4 and a partial support of PostgreSQL 7.3;</p> <p>This software is developed by a company called MicroOLAP. They have many other software concerning database. For more info and download see <a href="http://microolap.com/products/database/postgresql-designer/" target="_blank"><a href="http://microolap.com/products/database/postgresql-designer/" target="_blank">http://microolap.com/products/database/postgresql-designer/</a></a>.</p> <p>If you are looking for a GUI database modeling tool, hopefully these are some good tips.</p> <p>Andy</p> http://andywenk.github.io/postgresql/2009/07/06/database-modeling-tools http://andywenk.github.io/postgresql/2009/07/06/database-modeling-tools 2009-07-06T22:00:00+00:00 Very simple JS tab script Moin Moin, actually I needed a simple tab script for a page with tabbed navigation. Because coding is fun I decided to write my own, very simple tab script. In this case I used <a href="http://www.prototype-js.org" target="_blank">prototype</a>. The whole thing is for a little picture gallery which you can see here: <a href="http://www.woodheads.de/docs/picsframe.html." target="_blank">http://www.woodheads.de/docs/picsframe.html.</a> This is a page from my friends of my hometown in southern Germany. My job is to extend the existing code. There are two <em>div</em> areas marked with a <em>id</em>. The name of the <em>id</em> starts with <em>page_</em> as an identifier. prototype has a nice method to get all elements with a special attribute. In this case I grab the <em>div</em> elements having a <em>id</em> with <em>$$(&#8216;div[id]&#8217;)</em>. That makes it possible to iterate over the grabed div&#8217;s and handle only the needed objects - choosen with a simple regex. This is the basic HTML structure: <pre>&lt;span onclick="Pics.change_page('lutterhaus')"&gt;Lutterhaus&lt;/span&gt; | &lt;span onclick="Pics.change_page('plankstadt')"&gt;Plankstadt&lt;/span&gt; &lt;div id="page_plankstadt" style="display:none"&gt; &lt;div id="pic_gallery"&gt; &lt;div class="pics"&gt; &lt;img id="1" onclick="Pics.show_pic(this.id,'pla');" src="/img/1_th.jpg" alt="#" /&gt;&lt;br /&gt; &lt;img id="2" onclick="Pics.show_pic(this.id,'pla');" src="/img/2_th.jpg" alt="#" /&gt;&lt;br /&gt; &lt;/div&gt; &lt;div style="float:left;" id="pla" class="big_pic"&gt;&lt;img src="/images/1.jpg" /&gt;&lt;/div&gt; &lt;div class="pics"&gt; &lt;img id="3" onclick="Pics.show_pic(this.id,'pla');"src="/img/5_th.jpg" alt="#" /&gt;&lt;br /&gt; &lt;img id="4" onclick="Pics.show_pic(this.id,'pla');"src="/img/6_th.jpg" alt="#" /&gt;&lt;br /&gt; &lt;/div&gt; &lt;div style="clear:both"&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div id="page_lutterhaus" style="display:none"&gt; &lt;div id="pic_gallery"&gt; &lt;div class="pics"&gt; &lt;img id="5" onclick="Pics.show_pic(this.id,'pla');" src="/img/5_th.jpg" alt="#" /&gt;&lt;br /&gt; &lt;img id="6" onclick="Pics.show_pic(this.id,'pla');" src="/img/6_th.jpg" alt="#" /&gt;&lt;br /&gt; &lt;/div&gt; &lt;div style="float:left;" id="lutt" class="big_pic"&gt;&lt;img src="/images/1.jpg" /&gt;&lt;/div&gt; &lt;div class="pics"&gt; &lt;img id="7" onclick="Pics.show_pic(this.id,'pla');"src="/img/7_th.jpg" alt="#" /&gt;&lt;br /&gt; &lt;img id="8" onclick="Pics.show_pic(this.id,'pla');"src="/img/8_th.jpg" alt="#" /&gt;&lt;br /&gt; &lt;/div&gt; &lt;div style="clear:both"&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;</pre> And here the JavaScript code: <pre>&lt;script language="javascript"&gt; var Pics = { show_pic: function(id,area) { $(area).innerHTML = '&lt;img src="/images/' + id + '.jpg" /&gt;'; }, change_page: function(show) { // get the div elements with attribute id var elem = $$('div[id]'); // iterate over the div elements for(i = 0; i &lt; elem.length; i++) { // id does not match page_ if(!elem[i].id.match(/^page_/)) continue; // we ignore the page to be choosen if(elem[i].id == 'page_' + show) continue; // all matched elements will be hidden elem[i].style.display = 'none'; } // only the page we want to see is set to display $('page_' + show).style.display = 'block'; } } &lt;/script&gt;</pre> I think this is quiet simple and very lightweight. For sure <a href="http://script.aculo.us/" target="_blank">scriptaculous</a> and <a href="http://www.jquery.com" target="_blank">jQuery</a> (yes - and many other librarys) offer ready to go solutions for tabbed pages. But sometimes you just need a minimum of what these librarys can do and it&#8217;s faster to write it by yourself. Extending this for your needs hould be more than simple. Andreas http://andywenk.github.io/programming/2009/07/04/very-simple-js-tab-script http://andywenk.github.io/programming/2009/07/04/very-simple-js-tab-script 2009-07-04T22:00:00+00:00 PostgreSQL 8.4 released today Moin Moin, finally the PostgreSQL 8.4 database was released today. Let&#8217;s open a bottle of champaign and enjoy the new features. <p> <a href="http://www.postgresql.org/" target="_blank"><img src="http://media.tumblr.com/tumblr_kxyal3rJVe1qa0m1w.png" width="300"/></a></p> Cheers Andy P.S.: yes - the image is the link &#8230; http://andywenk.github.io/postgresql/2009/06/30/postgresql-8-4-released-today http://andywenk.github.io/postgresql/2009/06/30/postgresql-8-4-released-today 2009-06-30T22:00:00+00:00 balcony swiming pool Moin Moin, well - it&#8217;s 11:00 am and we have nearly 30&#160;C celsius her in Hamburg. And my daughter Kiana doesn&#8217;t need to go to the swimming bath because we have a swiming pool on our balcony ;-) <p><img src="http://media.tumblr.com/tumblr_kxyan5V1QL1qa0m1w.jpg"/></p> <p><img src="http://media.tumblr.com/tumblr_kxyancgCpl1qa0m1w.jpg"/></p> Have a nice day Andy http://andywenk.github.io/family/2009/06/29/balcony-swiming-pool-kiana http://andywenk.github.io/family/2009/06/29/balcony-swiming-pool-kiana 2009-06-29T22:00:00+00:00 PostgreSQL - PL/pgSQL UDF example Moin moin, actually one of our customers was asking if I can help him out with creating some vouchers for the online shop we made for him. You can visit the shop here: <a href="http://www.fashionroom.biz" target="_blank">fashionroom.biz</a>. The shop is - for sure - based on a PostgreSQL database. We did include a voucher mechanism but he was printing vouchers with numbers from 0001 up to 2500. The shop system does create random voucher codes like AYXVFY so I told him (in a joke) that he has a nice job now to change the 2500 voucher codes ;-). There are tow ways to create these vouchers. One would be to use PHP and fire 2500 INSERT querys into the database. Sure, as a prepared statement, it would be possible to avoid a load peak. But writing the script, transferring it to the server and so on &#8230; na! Annoying. So I decided to use a <em>user defined function</em> (UDF) written in PL/pgSQL. It&#8217;s quite easy but shows some features of udf&#8217;s in PL/pgSQL. Here it is: <pre> CREATE OR REPLACE FUNCTION create_voucher(int) RETURNS void AS $BODY$ DECLARE count ALIAS FOR $1; _cnt int := 1; _serial int; BEGIN SELECT max(vserial) INTO _serial FROM vouchers; _serial := _serial +1; WHILE _cnt &lt;= count LOOP INSERT INTO vouchers (vserial,created,vcode,title,percent) VALUES (_serial,NOW(),lpad(_cnt::varchar, 4, '0'),'30% voucher',30); _cnt := _cnt + 1; END LOOP; END $BODY$ LANGUAGE 'plpgsql' VOLATILE; </pre> As I said, it&#8217;s quite easy. The parameter in $1 is the max code number of the vouchers. vserial is a serial to put different vouchers together. It&#8217;s different to the id of the table which is serial (not shown here). So that&#8217;s the reason why I have to use the SELECT INTO query. _cnt is just a counter used inbetween the while loop and is increased by 1 each turn. Quite nice is the usage of lpad(). The vcode column is of datatype varchar. Here I simply cast the _cnt variable to a varchar and give it to lpad(). lpad() is now creating strings like 0001, 0015, 0425 and 2500. It fills 0&#8217;s from left to right until the string has a length of 4. Yeah - perfect. So that&#8217;s it. I think it&#8217;s much faster to use this instead of PHP. Andreas http://andywenk.github.io/postgresql/2009/06/14/postgresql-pl-pgsql-udf-example http://andywenk.github.io/postgresql/2009/06/14/postgresql-pl-pgsql-udf-example 2009-06-14T22:00:00+00:00 PHPUnit - testing PHP App Moin Moin, <p> I am a bad programmer! This is the conclusion after reading the first lines of <a href="http://sebastian-bergmann.de/" target="_blank">Sebastian Bergmanns</a> <a href="http://www.phpunit.de/manual/3.4/en/index.html" target="_blank">manual for PHPUnit</a>. </p> <p> <em>"Even good programmers make mistakes. The difference between a good programmer and a bad programmer is that the good programmer uses tests to detect his mistakes as soon as possible. The sooner you test for a mistake the greater your chance of finding it and the less it will cost to find and fix."</em> </p> <p> Ok - I will take my first words not too serious but I have to admit, that I do not develop test driven. The reason for that is the fact, that I never had an idea how to do it. I bought Sebastian Bergmanns <a href="http://www.amazon.de/PHPUnit-kurz-gut-Sebastian-Bergmann/dp/3897215152/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1244538197&amp;sr=8-2" target="_blank">"quick and dirty" PHPUnit</a> book some years ago but did not tune in to it any further. Another reason ist the fact, that <a href="http://www.e-unique.com" target="_blank">eUNIQUE</a> for example was started without any testing. Drilling tests afterwards into was expected too expensive. </p> <p> Since I have an account at <a href="http://github.com/andywenk" target="_blank">github</a> and are following some folks programming in Python or Ruby I recognized, that no software is going over the wire without tests. Which is a good thing in my opinion. Realizing that we have some really stupid bugs in our software (and also in other projects of mine) opened the disussion about using tests again - at least in my mind. But mentioning, using tests would definitely be a good idea was thrown to ground with the answer: there&#8217;s no time to do that. I don&#8217;t believe in that. I think the opposite is the truth. Thanks to a tweet from Stefan Bergmann, that the PHPUnit Manual has a new CSS style, I started to read it. I will drop my experiences here in the next few posts because now I will start using tests! </p> <p> <strong>Installing PHPUnit</strong> </p> <p> You know that I am using an <a href="http://www.debian.org" target="_blank">Debian based system</a>. So sorry to all the other geeks out there when I just explain stuff based on this OS. It shouldn&#8217;t be a big thing to adapt this to other OS. </p> <p> PHPUnit is delivered by <a href="http://pear.php.net/" target="_blank">PEAR</a>. I was running in a small issue when trying to install PHPUnit like explained in the manual. The reason was the wrong PEAR Installer. Fix it like this: </p> <p> If you never used PEAR or it might be old, simply reinstall it (just to be save): </p> <pre>$ sudo aptitude reinstall php-pear</pre> Next step is to add the channel for PHPUnit <pre>$ sudo pear channel-discover pear.phpunit.de Adding Channel "pear.phpunit.de" succeeded Discovery of channel "pear.phpunit.de" succeeded</pre> Good - now we try to install PHPUnit (output shortened): <pre>$ sudo pear install phpunit/PHPUnit ... phpunit/PHPUnit requires PEAR Installer (version &gt;= 1.8.1), installed version is 1.7.1 ... No valid packages found install failed</pre> <p> Ok - this did not work. So we have to update the PEAR installer. Checking out the PEAR page helps. Follow these steps (shortened): </p> <pre>$ sudo pear upgrade --force <a href="http://pear.php.net/get/PEAR-1.4.3.tar" target="_blank">http://pear.php.net/get/PEAR-1.4.3.tar</a> downloading PEAR-1.4.3.tar ... Starting to download PEAR-1.4.3.tar (Unknown size) .............done: 1,745,408 bytes WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update ... downloading Archive_Tar-1.3.3.tgz ... Starting to download Archive_Tar-1.3.3.tgz (18,119 bytes) ...done: 18,119 bytes upgrade ok: channel://pear.php.net/Archive_Tar-1.3.3 upgrade ok: channel://pear.php.net/PEAR-1.4.3 ... </pre> Ok - now we follow the instructions of upgrading the protocol: <pre>$ sudo pear channel-update pear.php.net Retrieving channel.xml from remote server Update of Channel "pear.php.net" succeeded</pre> Then we upgrade PEAR (output shortened): <pre> $ sudo pear upgrade PEAR downloading PEAR-1.8.1.tgz ... Starting to download PEAR-1.8.1.tgz (290,382 bytes) ........................................done: 290,382 bytes downloading XML_Util-1.2.1.tgz ... Starting to download XML_Util-1.2.1.tgz (17,729 bytes) ...done: 17,729 bytes upgrade ok: channel://pear.php.net/XML_Util-1.2.1 upgrade ok: channel://pear.php.net/PEAR-1.8.1</pre> And finally we install PHPUnit (shortened): <pre>$ sudo pear install phpunit/PHPUnit downloading PHPUnit-3.3.17.tgz ... Starting to download PHPUnit-3.3.17.tgz (272,418 bytes) ..........................................done: 272,418 bytes install ok: channel://pear.phpunit.de/PHPUnit-3.3.17</pre> <p> Tata &#8230; that&#8217;s it. If you want, you can install the optional packages. If want to install all the dependencies add the option &#8212;alldeps to the install command. The output will be like this (quite long - sorry): </p> <pre>$ sudo pear install --alldeps phpunit/PHPUnit WARNING: "pear/DB" is deprecated in favor of "pear/MDB2" phpunit/PHPUnit can optionally use PHP extension "pdo_sqlite" phpunit/PHPUnit can optionally use PHP extension "xdebug" (version &gt;= 2.0.0) pear/Log can optionally use PHP extension "sqlite" downloading PHPUnit-3.3.17.tgz ... Starting to download PHPUnit-3.3.17.tgz (272,418 bytes) ........................................done: 272,418 bytes downloading Image_GraphViz-1.2.1.tgz ... Starting to download Image_GraphViz-1.2.1.tgz (4,872 bytes) ...done: 4,872 bytes downloading Log-1.11.4.tgz ... Starting to download Log-1.11.4.tgz (44,275 bytes) ...done: 44,275 bytes downloading DB-1.7.13.tgz ... Starting to download DB-1.7.13.tgz (132,246 bytes) ...done: 132,246 bytes downloading MDB2-2.4.1.tgz ... Starting to download MDB2-2.4.1.tgz (119,790 bytes) ...done: 119,790 bytes downloading Mail-1.1.14.tgz ... Starting to download Mail-1.1.14.tgz (17,537 bytes) ...done: 17,537 bytes downloading Net_SMTP-1.3.2.tgz ... Starting to download Net_SMTP-1.3.2.tgz (10,247 bytes) ...done: 10,247 bytes downloading Auth_SASL-1.0.2.tgz ... Starting to download Auth_SASL-1.0.2.tgz (5,645 bytes) ...done: 5,645 bytes install ok: channel://pear.phpunit.de/PHPUnit-3.3.17 install ok: channel://pear.php.net/Image_GraphViz-1.2.1 install ok: channel://pear.php.net/Log-1.11.4 install ok: channel://pear.php.net/DB-1.7.13 install ok: channel://pear.php.net/MDB2-2.4.1 install ok: channel://pear.php.net/Mail-1.1.14 install ok: channel://pear.php.net/Net_SMTP-1.3.2 install ok: channel://pear.php.net/Auth_SASL-1.0.2 MDB2: Optional feature fbsql available (Frontbase SQL driver for MDB2) MDB2: Optional feature ibase available (Interbase/Firebird driver for MDB2) MDB2: Optional feature mysql available (MySQL driver for MDB2) MDB2: Optional feature mysqli available (MySQLi driver for MDB2) MDB2: Optional feature mssql available (MS SQL Server driver for MDB2) MDB2: Optional feature oci8 available (Oracle driver for MDB2) MDB2: Optional feature pgsql available (PostgreSQL driver for MDB2) MDB2: Optional feature querysim available (Querysim driver for MDB2) MDB2: Optional feature sqlite available (SQLite2 driver for MDB2) MDB2: To install optional features use "pear install pear/MDB2#featurename"</pre> <p> As you can see it&#8217;s quiet simple to install PHPUnit. The last step is to check wheter everything is good or not by writing a simple test (taken from the manual). Create a new file named StackTest.php and write the following into it: </p> <pre> <?php require_once 'PHPUnit/Framework.php'; class StackTest extends PHPUnit_Framework_TestCase { public function testPushAndPop() { $stack = array(); $this->assertEquals(0, count($stack)); array_push($stack, 'foo'); $this-&gt;assertEquals('foo', $stack[count($stack)-1]); $this-&gt;assertEquals(1, count($stack)); $this-&gt;assertEquals('foo', array_pop($stack)); $this-&gt;assertEquals(0, count($stack)); } } ?&gt;</pre> Now let&#8217;s see if we can use PHPUnit: <pre>$ phpunit --verbose StackTest PHPUnit 3.3.17 by Sebastian Bergmann. StackTest . Time: 0 seconds OK (1 test, 5 assertions)</pre> <p> If you see this result, everything works. </p> <p> That&#8217;s it for this time. In the next posts I will write about the integration of unit tests in our software - but don&#8217;t ask me when ;-). Please go and read the manual for PHPUnit in the meantime. Thanks to Sebastian Bergman! </p> Andy http://andywenk.github.io/programming/2009/06/08/testing-php-apps-with-phpunit http://andywenk.github.io/programming/2009/06/08/testing-php-apps-with-phpunit 2009-06-08T22:00:00+00:00 PHPUnit - testing php apps Moin Moin, I am a bad programmer! This is the conclusion after reading the first lines of <a href="http://sebastian-bergmann.de/" target="_blank">Sebastian Bergmanns</a> <a href="http://www.phpunit.de/manual/3.4/en/index.html" target="_blank">manual for PHPUnit</a>. <em>"Even good programmers make mistakes. The difference between a good programmer and a bad programmer is that the good programmer uses tests to detect his mistakes as soon as possible. The sooner you test for a mistake the greater your chance of finding it and the less it will cost to find and fix."</em> Ok - I will take my first words not too serious but I have to admit, that I do not develop test driven. The reason for that is the fact, that I never had an idea how to do it. I bought Sebastian Bergmanns <a href="http://www.amazon.de/PHPUnit-kurz-gut-Sebastian-Bergmann/dp/3897215152/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1244538197&amp;sr=8-2" target="_blank">"quick and dirty" PHPUnit</a> book some years ago but did not tune in to it any further. Another reason ist the fact, that <a href="http://www.e-unique.com" target="_blank">eUNIQUE</a> for example was started without any testing. Drilling tests afterwards into was expected too expensive. Since I have an account at <a href="http://github.com/andywenk" target="_blank">github</a> and are following some folks programming in Python or Ruby I recognized, that no software is going over the wire without tests. Which is a good thing in my opinion. Realizing that we have some really stupid bugs in our software (and also in other projects of mine) opened the disussion about using tests again - at least in my mind. But mentioning, using tests would definitely be a good idea was thrown to ground with the answer: there&#8217;s no time to do that. I don&#8217;t believe in that. I think the opposite is the truth. Thanks to a tweet from Stefan Bergmann, that the PHPUnit Manual has a new CSS style, I started to read it. I will drop my experiences here in the next few posts because now I will start using tests! <strong>Installing PHPUnit</strong> You know that I am using an <a href="http://www.debian.org" target="_blank">Debian based system</a>. So sorry to all the other geeks out there when I just explain stuff based on this OS. It shouldn&#8217;t be a big thing to adapt this to other OS. PHPUnit is delivered by <a href="http://pear.php.net/" target="_blank">PEAR</a>. I was running in a small issue when trying to install PHPUnit like explained in the manual. The reason was the wrong PEAR Installer. Fix it like this: If you never used PEAR or it might be old, simply reinstall it (just to be save): <pre>$ sudo aptitude reinstall php-pear</pre> Next step is to add the channel for PHPUnit <pre>$ sudo pear channel-discover pear.phpunit.de Adding Channel "pear.phpunit.de" succeeded Discovery of channel "pear.phpunit.de" succeeded</pre> Good - now we try to install PHPUnit (output shortened): <pre>$ sudo pear install phpunit/PHPUnit ... phpunit/PHPUnit requires PEAR Installer (version &gt;= 1.8.1), installed version is 1.7.1 ... No valid packages found install failed</pre> Ok - this did not work. So we have to update the PEAR installer. Checking out the PEAR page helps. Follow these steps (shortened): <pre>$ sudo pear upgrade --force <a href="http://pear.php.net/get/PEAR-1.4.3.tar" target="_blank">http://pear.php.net/get/PEAR-1.4.3.tar</a> downloading PEAR-1.4.3.tar ... Starting to download PEAR-1.4.3.tar (Unknown size) .............done: 1,745,408 bytes WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update ... downloading Archive_Tar-1.3.3.tgz ... Starting to download Archive_Tar-1.3.3.tgz (18,119 bytes) ...done: 18,119 bytes upgrade ok: channel://pear.php.net/Archive_Tar-1.3.3 upgrade ok: channel://pear.php.net/PEAR-1.4.3 ... </pre> Ok - now we follow the instructions of upgrading the protocol: <pre>$ sudo pear channel-update pear.php.net Retrieving channel.xml from remote server Update of Channel "pear.php.net" succeeded</pre> Then we upgrade PEAR (output shortened): <pre> $ sudo pear upgrade PEAR downloading PEAR-1.8.1.tgz ... Starting to download PEAR-1.8.1.tgz (290,382 bytes) ........................................done: 290,382 bytes downloading XML_Util-1.2.1.tgz ... Starting to download XML_Util-1.2.1.tgz (17,729 bytes) ...done: 17,729 bytes upgrade ok: channel://pear.php.net/XML_Util-1.2.1 upgrade ok: channel://pear.php.net/PEAR-1.8.1</pre> And finally we install PHPUnit (shortened): <pre>$ sudo pear install phpunit/PHPUnit downloading PHPUnit-3.3.17.tgz ... Starting to download PHPUnit-3.3.17.tgz (272,418 bytes) ..........................................done: 272,418 bytes install ok: channel://pear.phpunit.de/PHPUnit-3.3.17</pre> Tata &#8230; that&#8217;s it. If you want, you can install the optional packages. If want to install all the dependencies add the option &#8212;alldeps to the install command. The output will be like this (quite long - sorry): <pre>$ sudo pear install --alldeps phpunit/PHPUnit WARNING: "pear/DB" is deprecated in favor of "pear/MDB2" phpunit/PHPUnit can optionally use PHP extension "pdo_sqlite" phpunit/PHPUnit can optionally use PHP extension "xdebug" (version &gt;= 2.0.0) pear/Log can optionally use PHP extension "sqlite" downloading PHPUnit-3.3.17.tgz ... Starting to download PHPUnit-3.3.17.tgz (272,418 bytes) ........................................done: 272,418 bytes downloading Image_GraphViz-1.2.1.tgz ... Starting to download Image_GraphViz-1.2.1.tgz (4,872 bytes) ...done: 4,872 bytes downloading Log-1.11.4.tgz ... Starting to download Log-1.11.4.tgz (44,275 bytes) ...done: 44,275 bytes downloading DB-1.7.13.tgz ... Starting to download DB-1.7.13.tgz (132,246 bytes) ...done: 132,246 bytes downloading MDB2-2.4.1.tgz ... Starting to download MDB2-2.4.1.tgz (119,790 bytes) ...done: 119,790 bytes downloading Mail-1.1.14.tgz ... Starting to download Mail-1.1.14.tgz (17,537 bytes) ...done: 17,537 bytes downloading Net_SMTP-1.3.2.tgz ... Starting to download Net_SMTP-1.3.2.tgz (10,247 bytes) ...done: 10,247 bytes downloading Auth_SASL-1.0.2.tgz ... Starting to download Auth_SASL-1.0.2.tgz (5,645 bytes) ...done: 5,645 bytes install ok: channel://pear.phpunit.de/PHPUnit-3.3.17 install ok: channel://pear.php.net/Image_GraphViz-1.2.1 install ok: channel://pear.php.net/Log-1.11.4 install ok: channel://pear.php.net/DB-1.7.13 install ok: channel://pear.php.net/MDB2-2.4.1 install ok: channel://pear.php.net/Mail-1.1.14 install ok: channel://pear.php.net/Net_SMTP-1.3.2 install ok: channel://pear.php.net/Auth_SASL-1.0.2 MDB2: Optional feature fbsql available (Frontbase SQL driver for MDB2) MDB2: Optional feature ibase available (Interbase/Firebird driver for MDB2) MDB2: Optional feature mysql available (MySQL driver for MDB2) MDB2: Optional feature mysqli available (MySQLi driver for MDB2) MDB2: Optional feature mssql available (MS SQL Server driver for MDB2) MDB2: Optional feature oci8 available (Oracle driver for MDB2) MDB2: Optional feature pgsql available (PostgreSQL driver for MDB2) MDB2: Optional feature querysim available (Querysim driver for MDB2) MDB2: Optional feature sqlite available (SQLite2 driver for MDB2) MDB2: To install optional features use "pear install pear/MDB2#featurename"</pre> As you can see it&#8217;s quiet simple to install PHPUnit. The last step is to check wheter everything is good or not by writing a simple test (taken from the manual). Create a new file named StackTest.php and write the following into it: <pre> <?php require_once 'PHPUnit/Framework.php'; class StackTest extends PHPUnit_Framework_TestCase { public function testPushAndPop() { $stack = array(); $this->assertEquals(0, count($stack)); array_push($stack, 'foo'); $this-&gt;assertEquals('foo', $stack[count($stack)-1]); $this-&gt;assertEquals(1, count($stack)); $this-&gt;assertEquals('foo', array_pop($stack)); $this-&gt;assertEquals(0, count($stack)); } } ?&gt;</pre> Now let&#8217;s see if we can use PHPUnit: <pre>$ phpunit --verbose StackTest PHPUnit 3.3.17 by Sebastian Bergmann. StackTest . Time: 0 seconds OK (1 test, 5 assertions)</pre> If you see this result, everything works. That&#8217;s it for this time. In the next posts I will write about the integration of unit tests in our software - but don&#8217;t ask me when ;-). Please go and read the manual for PHPUnit in the meantime. Thanks to Sebastian Bergman! Andy http://andywenk.github.io/2009/06/08/phpunit-testing-php-apps http://andywenk.github.io/2009/06/08/phpunit-testing-php-apps 2009-06-08T22:00:00+00:00 PostgreSQL: simple trigger for email Moin Moin, I actually had a little usability problem with a customer using the online registration from <a href="http://www.e-unique.com" target="_blank">eUNIQUE</a>. The attendees have to login by giving a username and a password. In this case and to keep it as simple as possible, the email address is the username. Actually I did not realize, that people still write their email addresses in camle case. For example: Andy.Wenk@gmail.com or Andy.wenk@gmail.com These addresses are different for the authentication process. And that made problems for the attendees, because the people forgot in which version they saved their username. So I decided to avoid this by only allowing lower case written usernames. It would be annoying to tell the customer &#8220;please correct your username (only lower case)&#8221;. That means the application has to deal with that. Do that with PHP? No, because there are more places in the application where the username is changable (only some - don&#8217;t worry ;-) ). So the easiest way is to use a trigger in PostgreSQL. While receivieng the username, it will be changed to lowercase using the function lowercase(). It looks like this: <pre>CREATE OR REPLACE FUNCTION user_lower_username() RETURNS "trigger" AS $BODY$ BEGIN new.email := lower(new.email); new.username := lower(new.username); return new; END $BODY$ LANGUAGE 'plpgsql' VOLATILE; CREATE TRIGGER user_lower_username BEFORE INSERT OR UPDATE ON users FOR EACH ROW EXECUTE PROCEDURE user_lower_username();</pre> Another advantage of using this trigger is the fact, that the attendees are not able to make a new account by simply writing their username in a different way (e.g Andy.wenk instead of andy.wenk). By the way - I also lower the email address as you can see in the function. The only place we had to change the code was the part where we compare the username given by the user (while logging in) with the username in the database. We have to use the PHP function str_to_lower() to compare lowercase with lowercase. Simple &#8230; isn&#8217;t it? Andreas http://andywenk.github.io/postgresql/2009/06/04/postgresql-simple-trigger-for-email http://andywenk.github.io/postgresql/2009/06/04/postgresql-simple-trigger-for-email 2009-06-04T22:00:00+00:00 svn:ignore property usage Moin Moin, first to my fans at <a href="http://www.nmmn.com" target="_blank">NMMN</a>: cooool ;-) Ok - a little more serious. It&#8217;s kind of a hobby or philosophy to find the best editor for hacking. Have you found your&#8217;s yet? I know that all the MAC users mostly use <a href="http://macromates.com/" target="_blank">TextMate</a>. And a lot of Linux users like <a href="http://www.eclipse.org/" target="_blank">eclipse</a>. After having tested and used eclipse for about two years (and three versions and three times fuckups with upgrading) I am using <a href="http://www.netbeans.org/downloads/index.html" target="_blank">Netbeans</a> these days. I installed the PHP and Python version which is running well. One point that made me go crazy all the time is the <a href="http://subversion.tigris.org/" target="_blank">SVN</a> implementation in eclipse and Netbeans. Well, the developers of Netbeans integrated svn assistance in the standard version. But it&#8217;s working so la la. So I decided to use svn from the shell. Since I use <a href="http://github.com/andywenk" target="_blank">git</a> for some stuff, this is even more familiar to me (I know that there are git clients - but hey come on! that&#8217;s not cool ;-) ). In each project there are always files or directories which you don&#8217;t want to have in your svn repo. So you want to use the svn:ignore command. Here is a brief introduction of it&#8217;s usage. <strong>svn property commands</strong> Basically you can use these property commands with svn: <pre>propdel (pdel, pd) propedit (pedit, pe) propget (pget, pg) proplist (plist, pl) propset (pset, ps)</pre> This is part of the output when you type <pre>$ svn help</pre> For ignoring a file or a directory you use basically pl (proplist), pg (propget) and ps (propset). <strong>Using svn:ignore</strong> Let&#8217;s say we are in the working directory of our project. Because we use Netbeans, there is a folder called &#8220;nbprojects&#8221; with project settings in it. We don&#8217;t want this folder to be added to the svn repo. Also, there is a file called &#8220;info&#8221; with some reminding stuff. This file is also not needed in the svn repo. So let&#8217;s start by ignoring the folder: <pre>$ ll insgesamt 4 -rw-r--r-- 1 duke duke 0 2009-05-28 12:24 info drwxr-xr-x 3 duke duke 4096 2009-05-28 12:18 nbproject $ svn ps svn:ignore nbproject . Eigenschaft »svn:ignore« für ».« gesetzt</pre> The command line means, that we use the program svn and its command ps (propset) with the option svn:ignore to set the property for this folder ( . at the end) with ignoring the folder nbproject. Let&#8217;s see if this is correct: <pre>$ svn pl Eigenschaften zu ».«: svn:ignore</pre> Ok - that means, we have set a svn property for the folder . (the actual folder). Now let&#8217;s examine what exactly is ignored: <pre>$ svn pg svn:ignore nbproject</pre> Yep - that means, the folder nbproject is ognored for commits - as expected. <strong>adding more files or folders to the svn:ignore list</strong> This is importnat now. If you want to add more folders or files to the svn:ignore list, you have to keep in mind, that each usage of svn ps svn:ignore will overwrite the list for this folder. So you have to add the allready ignored files / folders and the new one again to the list. The first approach will not bring the expected result: <pre>$ svn ps svn:ignore info . Eigenschaft »svn:ignore« für ».« gesetzt $ svn pg svn:ignore info --&gt; nbproject is lost</pre> The better way: <pre>$ svn ps svn:ignore nbproject,info . Eigenschaft »svn:ignore« für ».« gesetzt $ svn pg svn:ignore nbproject,info</pre> And there is another way to avoid overwriting allready set propertys. Use the command <pre>$svn propedit svn:ignore .</pre> This will call your standard editor and is giving you the possibility to write down all the files or folders to be ignored in the actual choosen folder. I recommend to use this way &#8216;cause it&#8217;s the safest. That&#8217;s it. <strong>Deleting a property</strong> Sure we need also a possibility to delete a property. Therfore we use pd (propdel). Here is the usage: <pre> $ svn pd svn:ignore . Eigenschaft »svn:ignore« wurde von ».« gelöscht.</pre> That means we deleted the property svn:ignore form the folder . . Using svn pg svn:ignore will now return no result. So have fun using svn! Andreas P.S.: the online svn book is <a href="http://svnbook.red-bean.com/" target="_blank">here</a> http://andywenk.github.io/server/2009/05/27/svn-ignore-usage-because-of-poor-editor http://andywenk.github.io/server/2009/05/27/svn-ignore-usage-because-of-poor-editor 2009-05-27T22:00:00+00:00 Linux Kubuntu - my new sofa machine Moin Moin, after having some fuckups with Windows XP and not having the ability to code in a well known environment, I decided to trash Windows XP and install Kubuntu. Why? &#8216;Cause it&#8217;s nice. It brings all the advantages from Ubuntu based on Debian and has the really cool looking KDE. I never used it before but after some hours working and looking at it, I am satisfied. I have a RaLink RT2500 WLAN adapter onboard and also a PCI Buffalo card. No problem. Kubuntu offers the option to install the drivers in the Application Launcher &gt; System &gt; Hardware Drivers. Cool! Next step was to get the grafic chipset work. Hm - that costs me some google searches but it&#8217;s also really simple. The openchrome driver is on board by default since Ubuntu 8.04. The only thing I had to do is activate it and write some extra stuff into the xorg.conf. By the way - I have one of those Via Unichrome PM800 onboard grafic chipsets. Here is what I had to change in xorg.conf: <pre>$ vi /etc/X11/xorg.conf Section "Device" Identifier "Configured Video Device" Driver "openchrome" EndSection Section "Screen" Identifier "Default Screen" Monitor "Configured Monitor" Device "Configured Video Device" Subsection "Display" Depth 8 Modes "1024x768" "800x600" ViewPort 0 0 Depth 16 Modes "1024x768" "800x600" ViewPort 0 0 Depth 24 Modes "1024x768" "800x600" ViewPort 0 0 EndSubsection EndSection</pre> After that stop the display manager kdm and restart it. That&#8217;s it. Take care if you find stuff concerning the Via Unichrome driver. This is really all you have to do. No complicated installation processes as described a lot. So for me this is really a cool Linux. I am going to setup the rest of my needed stuff and then forget about all that never ending installation nights &#8230; Andy http://andywenk.github.io/server/2009/05/22/linux-kubuntu-my-new-sofa-laptop http://andywenk.github.io/server/2009/05/22/linux-kubuntu-my-new-sofa-laptop 2009-05-22T22:00:00+00:00 Python couchdbkit <p>Moin Moin,</p> <p>I just received a tweet by Benoit C., that he updated his <a href="http://bitbucket.org/benoitc/couchdbkit/" target="_blank">couchdbkit repository at bitbucket</a>. Here is the description in his own words:</p> <p>"Trying to improve couchdb experience in python. CouchDBKit is a framework to allow your python applicationto use CouchDB. Discuss with us on Google group&#160;: <a href="http://groups.google.com/group/couchdbkit" target="_blank"><a href="http://groups.google.com/group/couchdbkit" target="_blank">http://groups.google.com/group/couchdbkit</a></a> or follow us on Twitter: <a href="http://twitter.com/eengura" target="_blank"><a href="http://twitter.com/eengura" target="_blank">http://twitter.com/eengura</a></a>.&#8221;</p> <p>So for all Python fans working with couchdb - you have to check this out.</p> <p>Andy</p> http://andywenk.github.io/couchdb/2009/05/09/python-couchdbkit http://andywenk.github.io/couchdb/2009/05/09/python-couchdbkit 2009-05-09T22:00:00+00:00 Social media sketch by Birger Hartung <p>Moin Moin,</p> <p>a former customer and now friend of mine, <a href="http://birgerking.net/" target="_blank">Birger Hartung</a>, was creating some absolute amazing sketches concerning &#8220;social media&#8221;. He&#8217;s calling himself a internet visionary and his philosophy about the internet is 5 years ahead. Check it out by yourself - I like his thoughts a lot. Even when I do not fully agree all the time &#8230; </p> <p><a href="http://www.flickr.com/photos/birgerking/3432898656/" target="_blank">smsketch_easter_edition_09</a></p> <p>Have fun and tell me what you think about &#8230;</p> <p>Andy</p> http://andywenk.github.io/www/2009/05/06/social-media-sketch-by-birger-hartung http://andywenk.github.io/www/2009/05/06/social-media-sketch-by-birger-hartung 2009-05-06T22:00:00+00:00 postgreSQL pg_ctlcluster auf dem Debian System Moin Moin, es führen bekanntlich viele Wege nach Rom. So ist es auch beim Starten und Stoppen der PostgreSQL. Das ganze sieht auf einem Debian System folgendermaßen aus. <h3>1. Per init Script</h3> Das ist so ziemlich der einfachste Weg. <pre>root@seven:~# /etc/init.d/postgresql-8.1 Usage: /etc/init.d/postgresql-8.1 {start|stop|restart|reload|force-reload|status|autovac-start|autovac-stop|autovac-restart}</pre> <h3>2. Per pg_ctlcluster </h3> Das ist ein Distributions Tool von Debian. Im Ordner /usr/bin/ gibt es folgende tools: <pre>root@seven:~# ll /usr/bin/pg_* - -rwxr-xr-x 1 root root 23704 4. Nov 22:37 /usr/bin/pg_config - -rwxr-xr-x 1 root root 24118 21. Jul 10:47 /usr/bin/pg_createcluster - -rwxr-xr-x 1 root root 18980 21. Jul 10:46 /usr/bin/pg_ctlcluster - -rwxr-xr-x 1 root root 3552 3. Feb 2008 /usr/bin/pg_dropcluster lrwxrwxrwx 1 root root 37 24. Nov 14:37 /usr/bin/pg_dump -&gt; ../share/postgresql-common/pg_wrapper lrwxrwxrwx 1 root root 37 24. Nov 14:37 /usr/bin/pg_dumpall -&gt; ../share/postgresql-common/pg_wrapper - -rwxr-xr-x 1 root root 1293 17. Okt 2007 /usr/bin/pg_lsclusters lrwxrwxrwx 1 root root 37 24. Nov 14:37 /usr/bin/pg_restore -&gt; ../share/postgresql-common/pg_wrapper - -rwxr-xr-x 1 root root 22253 31. Mär 2008 /usr/bin/pg_upgradecluster</pre> Und so wird&#8217;s genutzt: <pre>root@seven:~# pg_ctlcluster which pg_ctluster Usage: /usr/bin/pg_ctlcluster &lt; version &gt; &lt; cluster &gt; &lt; action &gt;</pre> wobei action = start|stop|restart|reload|autovac-start|autovac-stop|autovac-restart Beispiel: <pre>root@seven:~# pg_ctlcluster 8.1 main start</pre> <h3>3. Mit Postgres&#8217;schen hauseigenen tool pg_ctl</h3> Das geht natürlich auch. Dafür muss man allerdings einige Dinge vorbereiten. Zuerstmal muss man der User postgres sein und wechselt in das Homeverzeichnis: <pre>root@seven:~# su postgres postgres@seven:/root$ cd postgres@seven:~$</pre> Dort bearbeitet man zuerst die .bashrc Datei oder legt diese an. Der Inhalt sollte mindestens dieser sein: <pre>export PATH=/usr/lib/postgresql/8.1/bin:$PATH export PGDATA=/var/lib/postgresql/8.1/main/ export PGPORT=5432</pre> Zum einen fürgen wir der Umgebungsvariablen PATH den Eintrag zu pg_ctl hinzu. AUsserdem legen wir noch das Data Directory der PostgreSQL und den Port fest. Wenn wir eine andere PostgreSQL laufen lassen wollen, z.B. auf Port 5433&#160;müsste das geändert werden. Das war&#8217;s erstmal. Wechseln wir jetzt in das main Verzeichnis und setzen pg_ctl start ab, wird das nicht klappen, weil die postgresql.conf noch fehlt: <pre>postgres@seven:~$ cd 8.1/main/ postgres@seven:~$ cd 8.1/main$pg_ctl start postgres@seven:~$ cd 8.1/main$postmaster kann nicht auf die Serverkonfigurationsdatei »/var/lib/postgresql/8.1/main/postgresql.conf« zugreifen: Datei oder Verzeichnis nicht gefunden</pre> Also setzen wir einen Symlink: <pre> postgres@seven:~$ cd 8.1/main$ln -s /etc/postgresql/postgresql.conf </pre> Wichtig ist noch zu erwähnen, dass pg_ctl auf jeden Fall die Datei PG_VERSION in diesem Verzeichnis erwartet. Übrigens kann man diesen Befehl auch im Verzeichnis /etc/postgresql/ erfolgreich absetzen. Dort sind bereits alle Verweise vorhanden. So, das war&#8217;s. An dieser Stelle mal wieder ganz herzlichen Dank an unseren Sysadmin Andreas Putzo der wie immer mit Rat und Tat zur Verfügung stand ;-) Andreas http://andywenk.github.io/postgresql/2008/12/11/postgresql-pg-ctlcluster-auf-dem-debian http://andywenk.github.io/postgresql/2008/12/11/postgresql-pg-ctlcluster-auf-dem-debian 2008-12-11T23:00:00+00:00 svn - commit E-Mails einrichten Moin Moin, na weil das Thema svn so spannend ist, hier gleich noch ein kleines HOW TO für das Einrichten von commit E-Mails. Das heisst, jedes mal wenn ein svn commit ausgeführt wird, wird eine E-Mail an eine oder mehrere Personen geschickt. <h3>1. subversion-tools installieren</h3> Zuerst muss eine Erweiterung für Subversion installiert werden. Auf einem Debian System nutzen wir wieder den Paketmanager apt oder aptitude. <pre> root@server: apt-get install subversion-tools </pre> <h3>2. email Adresse in commit-email.pl angeben</h3> Nun suchen wir den Ordner in welchem die Datei commit-email.pl liegt. Der Ordner heisst hook-scripts. <pre>root@server: dpgk -L subversion-tools [...] /usr/share/subversion/hook-scripts/commit-email.pl [...] </pre> Das merken wir uns. Als nächstes wechseln wir in das Verzeichnis, in welchem unser svn Repository liegt und dort in den Ordner hooks: <pre> root@server:cd /var/lib/svn/repo1/hooks root@server:/var/lib/svn/repo1/hooks# </pre> Dort kopieren wir jetzt die Datei post-commit.tmpl zu post-commit und bearbeiten diese: <pre> root@server:/var/lib/svn/repo1/hooks# cp post-commit.tmpl post-commit root@server:/var/lib/svn/repo1/hooks# chmod 755 post-commit root@server:/var/lib/svn/repo1/hooks# vi post-commit </pre> Letztendlich müssen wir nur ein paar Zeilen am Ende der Datei einfügen: <pre> #!/bin/sh # POST-COMMIT HOOK # # The post-commit hook is invoked after a commit. Subversion runs # this hook by invoking a program (script, executable, binary, etc.) # named 'post-commit' (for which this file is a template) with the # following ordered arguments: # # [1] REPOS-PATH (the path to this repository) # [2] REV (the number of the revision just committed) # [...] REPOS="$1" REV="$2" /usr/share/subversion/hook-scripts/commit-email.pl $REPOS $REV --from svn@emailadr.com meine@mailadr.com </pre> Was passiert hier? Nach dem subversion einen commit abgefeuert hat, wird dieses script post-commit aufgerufen. Dem script werden zwei Parameter übergeben. Erstens der Pfad zum repositroy in $1 und zweitens die Revision Nummer in $2. Danach wird das Perl script commit-email.pl aufgerufen (deshalb haben wir uns den Pfad dorthin gemerkt) wobei wiederum Parameter übergeben werden. Zuerst der Pfad zum Repository, die revision Nummer, eine &#8220;From:&#8221; E-Mail Adresse und den Empfänger. Es können noch weitere Parameter angegeben werden. Um alle Optionen zu sehen, einfach mal in das verzeichnis wechseln in welchem das PERL Script liegt und ausführen: <pre> root@server: cd /usr/share/subversion/hook-scripts/ root@server:/usr/share/subversion/hook-scripts# perl ./commit-email.pl ./commit-email.pl: too few arguments. usage (commit mode): ./commit-email.pl REPOS REVNUM [[-m regex] [options] [email_addr ...]] ... usage: (revprop-change mode): ./commit-email.pl --revprop-change REPOS REVNUM USER PROPNAME [-d diff_file] \ [[-m regex] [options] [email_addr ...]] ... options are: --from email_address Email address for 'From:' (overrides -h) -h hostname Hostname to append to author for 'From:' -l logfile Append mail contents to this log file -m regex Regular expression to match committed path -r email_address Email address for 'Reply-To:' -s subject_prefix Subject line prefix --diff y|n Include diff in message (default: y) (applies to commit mode only) [... weiter Erklärungen] </pre> <h3>Verbesserung</h3> Momentan ist das ganze so eingestellt, dass die E-Mail an einen Empfänger geht. Denkbar bzw. sinvoller ist es aber, das an eine Mailinglist E-Mail Adresse zu senden. Dann erhalten alle Beteiligten Entwickler die E-mail und können nachverfolgen, wer was wann geändert oder gecoded hat. Andreas http://andywenk.github.io/server/2008/11/22/svn-commit-e-mails-einrichten http://andywenk.github.io/server/2008/11/22/svn-commit-e-mails-einrichten 2008-11-22T23:00:00+00:00 svn - einen svn Server einrichten Moin Moin, mal wieder was zu svn. Es geht darum wie ich einen svn Server - ich nenn das mal so - mit Apache2 einrichte. Der Witz dabei ist, dass der Apache2 so konfiguriert wird, dass wir sehr einfach per http Schnittstelle auf das Repository zugreifen können. Also Abfahrt. <h3>1. svn installieren</h3> Wie immer betrachte ich die Installation unter einem Debian Linux als User root. Die Installation ist denkbar einfach, wobei wir zum einen svn und zum anderen die Erweiterung für den Apache2 installieren müssen: <pre> root@server: aptitude install subversion libapache2-svn </pre> <h3>2. Modul dav_svn aktivieren</h3> Jetzt aktivieren wir das Apache2 Modul dav_svn. Dazu wechseln wir in das Modul Verzeichnis des Apache und aktivieren es mit dem Apache Programm a2enmod: <pre> root@server: cd /etc/apache2/mods-available/ root@server:/etc/apache2/mods-available# a2enmod dav_svn </pre> <h3>3. Das Modul dav_svn konfigurieren</h3> Nachdem alles installiert und aktiviert ist, geht&#8217;s jetzt an die Konfiguration. Dazu bearbeiten wir die Datei dav_svn.conf. <pre> root@server: cd /etc/apache2/mods-enabled/ root@server:/etc/apache2/mods-enabled# vi dav_svn.conf </pre> Der Inhalt der Datei sieht prinzipiell so aus. Ich lasse alle Kommentar weg und schreibe eigen dazu: <pre>&lt;Location /svn&gt; # muss auskommentiert werden, damit das Repository aktiviert wird DAV svn # wir wollen mehrere Repositorys verwalten SVNParentPath /var/lib/svn # Die Authentifizierung erfolgt über die Datei dav_svn.passwd AuthType Basic AuthName "Subversion Repository" AuthUserFile /etc/apache2/dav_svn.passwd # Wir wollen über mod_authz_svn die Rechte für den Zugriff auf die Repositorys steuern AuthzSVNAccessFile /etc/apache2/dav_svn.authz # Um die Repositorys auschecken zu können, muss ein gültiger User existieren Require valid-user &lt;/Location&gt;</pre> Ich habe in einem früheren Post schon erklärt, wie man mod_authz_svn einrichtet. Den Post <a href="http://blog.netzmeister-st-pauli.de/index.php/2008/09/22/svn-authentifizierung-mit-mod_authz_svn" target="_blank">findest Du hier</a>. Wenn wir alles erledigt haben starten wir den Webserver neu. <h3>4. Einen User anlegen</h3> Einen user legen wir an, indem wir diesen mit dem Program htpasswd in die Datei dav_svn.passwd eintragen. Dazu wechseln wir zuerst ins entsprechende Verzeichnis: <pre> root@server: cd /etc/apache2/ &lt;em&gt;wenn die Datei noch nicht existiert&lt;/em&gt; root@server:/etc/apache2/htpasswd -c dav_svn.passwd root@server:/etc/apache2# htpasswd dav_svn.passwd [user] </pre> -&gt; Dann zweimal Passwort eingeben <h3>5. Ein Repository erstellen</h3> So, alles eingestellt. Jetzt erstellen wir ein Repository. Dazu wechseln wir in das Verzeichnis, in welchem die Repository&#8217;s liegen sollen und nutzen das Program svnadmin wiederum als User root: <pre> root@server: cd /var/lib/svn root@server:/var/lib/svn# svnadmin create repositroy_neu </pre> Damit haben wir ein Repository namens repository_neu erstellt. Aber Achtung. Damit das Repository über das web betrachtet werden kann, müssen wir die Rechte ändern. Ich gehe davon aus, dass der Apache2 User und die Group www-data heisst: <pre> root@server:/var/lib/svn# chown -R www-data repository_neu/ </pre> Testen wir das Ganze und geben wir die URL des Repository&#8217;s im Browser ein: <em><a href="http://www.server.de/svn/repository_neu" target="_blank">http://www.server.de/svn/repository_neu</a></em> Wir müssen eine http Authentifizerung machen. Und danach sehen wir so was wie das hier: <img src="http://media.tumblr.com/tumblr_kyf21ql3FB1qa0m1w.png"/> Damit haben wir&#8217;s auch schon geschafft. <h3>6. Ein Projekt auschecken</h3> Hier noch ganz kurz, wie man ein svn Repository auf der Shell auscheckt: <pre> user@server: cd /tmp user@server:/tmp/ svn co htp://www.server.de/svn/repository_neu -username [user] Anmeldebereich: <a href="http://www.server.de:80" target="_blank">http://www.server.de:80</a> Subversion Repository Passwort für »[user]«: ********* Ausgecheckt, Revision 0. user@root:/tmp/ </pre> Für Hilfe zu svn einfach svn help oder svn help [Befehl] eingeben. Dann viel Spass Andreas http://andywenk.github.io/server/2008/11/18/svn-einen-svn-server-einrichten http://andywenk.github.io/server/2008/11/18/svn-einen-svn-server-einrichten 2008-11-18T23:00:00+00:00