Simple wget crawler for list of files

Posted on 6. August 2015 Comments

This script could be helpful to download a set of files from a webserver, that you don’t have (S)FTP access to. The input file consists of a list of filenames, one name each line.

while IFS= read -r line; do
wget -nc -R --spider $FULLURL
done < "$file"

At first, the first command line argument is saved into the variable file. Then the Webserver address is saved to the WEBSERVER variable. IFS stands for Internal Field Separator. It’s used to read line by line through the file in the while loop that ends in the last line. Inside of the loop, the read line is concatenated with the webserver address into FULLURL. Then, wget is used with the parameters -nc for checking if the file is not already present in the current folder, -R for downloading and –spider for checking the existence on the webserver.

You can find the script on GitHub.

Flattr this!

Collect currency exchange rates in a MySQL database with PHP and API

Posted on 4. August 2015 Comments

If you work in a company that buys and sells goods in many different currencies, it might be a good idea, to use the latest exchange rates. Also, it might be useful, to store old exchange rates to clarify/verify old business decisions. If once a day is enough for you, offers a free simple Rest API. Because most of the code at my work is written in PHP but I usually use the request in JavaScript and Python, I was looking for something similar and found the requests library by rmccue on GitHub. It’s easily installed by Composer (the PHP counterpart to npm or pip):

$ curl -sS | php

Now open a texteditor and write the following:

    "require": {
        "rmccue/requests": ">=1.0"

Save the file as composer.json

php composer.phar install

Now there is a folder called vendor, and in it you will find the rmccue/requests folder. The API is pretty straight forward, as explained on the front page

$BASE = 'EUR';
$request = Requests::get('' . $BASE, array('Accept' => 'application/json'));
if ($request->status_code == 200) {
$response = json_decode($request->body);
$GBP = $response->rates->GBP;
$CAD = $response->rates->CAD;
$USD = $response->rates->USD;
$NOK = $response->rates->NOK;
$CNY = $response->rates->CNY;
$rBASE = mysql_real_escape_string($response->base);
$date = mysql_real_escape_string($response->date);
$currencies = mysql_real_escape_string("1.0, $USD, $GBP, $NOK, $CNY, $CAD");
$qry = "INSERT INTO `EXCHANGE-RATES-FIXERIO`(date, base, eur, usd, gbp, nok, cny, cad) VALUES ('$date', '$rBASE', $currencies);";
$insert = mysql_query($qry, $MYSQLCONNECTION) or print mysql_error();

So the Request file from the library is included. Also, I defined the database connection earlier, there’s lot’s of documentation for that. Because we are from Europe, I chose Euro (EUR) as the base currency. Apart from the get() method, you need nothing else, to send a request. If the request returns an OK(200), the response is read and saved into different variables, e.g. for British Pounds, US Dollar, Canadian Dollar, Chinese Renminbi and Norwegian Krone. Just to make sure we have the right base, it’s also parsed. The date can be used as a String, even though the MySQL Table might use a Date(see below). The responses are then escapes special string, just in case something goes wrong on at It is then inserted into the table.

The table could look like this:

`date` date NOT NULL,
`base` varchar(3) NOT NULL,
`eur` double NOT NULL,
`usd` double NOT NULL,
`gbp` double NOT NULL,
`nok` double NOT NULL,
`cny` double NOT NULL,
`cad` double NOT NULL


You can also find this code on GitHub.

Flattr this!

Using nanoc for podcast feeds

Posted on 23. Juli 2015 Comments

Nanoc is a static site generator much like jekyll or octopress, but with a more minimalistic approach. These generators are not necessarily the most suitable choice for a podcast website, but it’s possible and you might save up on webspace and traffic when you use GitHub or Neocities.

Creating the podcast feed is basically like writing a normal Atom feed for the blog, since podcast feeds ARE indeed feeds with an enclosure tag in which the URL to the audio or video file is placed. This guide does not include the itunes tags. I might add it one day. Follow the instructions and use the documentation for the Helper Blogging. Tag your podcast episodes as kind:article.

The media files are placed in content/mp3 and content/opus, which is where the links in the feeds will point to later.

I invented the fields mp3 and opus, since these are the file formats I want to use. The values are the filenames. The header of a new episode/post would look like

title: 001 - Podcast Episode Title
created_at: 2015-03-14 09:00:00 +0000
kind: article
tags: [podcast,topic]
mp3: 001-podcast-episode-title.mp3
opus: 001-podcast-episode-title.opus

This has to be filled manually everytime, so make sure you have the exact filename, as some podcast clients won’t allow correction of the URL.

The next step is to write different feeds for the formats. For that, I’m using the new field format, which will be interpreted by the Helper class later on. For example, I called my normal feed blogfeed and the podcast feeds mp3feed and opusfeed. Create the file blogfeed.erb in the content folder and fill it with the following:

<%= atom_feed :title => 'repats podcast blog', :author_name => 'repat',
:author_uri => '', :limit => 10, :format => 'blog' %>

The mp3feed.erb and opusfeed.erb are filled accordingly:

<%= atom_feed :title => 'repats podcast mp3', :author_name => 'repat',
:author_uri => '', :limit => 10, :format => 'mp3' %>

<%= atom_feed :title => 'repats podcast opus', :author_name => 'repat',
:author_uri => '', :limit => 10, :format => 'opus' %>

The next step is to use the Blogging locally in your nanoc installation. To do that you need to copy it from the gems folder into your lib folder. For me, that was

$ cp /var/lib/gems/1.9.1/gems/nanoc-3.7.5/lib/nanoc/helpers/blogging.rb lib/

It should be included like this in the lib/default.rb

include Nanoc3::Helpers::Blogging

Add the following attribute to the AtomFeedBuilder class

attr_accessor :format

If you don’t trust yourself to always remember the files you might want to  add this exception to the validate_feed_item function

if format.nil?
raise'Cannot build Atom feed: no format(mp3,opus,blog) in params, item or site config')

After the # Add link comment is a good place to insert the  enclosure tag. File.size() will only work if the files are there and the exact same name. This code could probably be written a bit more safely, but I’m not a ruby developer and since I will have an mp3 file and and opus file in every post it’s not a problem this way.

# Add podcast enclosure
if format == 'mp3'"" + a[:mp3],length:File.size("content/mp3/" + a[:mp3]), type:"audio/mpeg", rel:"enclosure")
elsif format == 'opus'"" + a[:opus],length:File.size("content/opus/" + a[:opus]), type:"audio/mpeg", rel:"enclosure")

To interpret the mp3 and opus attribute from earlier in the actual post, the last step is to add this line to the atom_feed function:

      builder.format            = params[:format]

You might need to install builder to let this run

$ sudo gem install builder

The only thing left to do is to edit the Rules file:

compile '/blogfeed' do
filter :erb
compile '/mp3feed' do
filter :erb
compile '/opusfeed' do
filter :erb
route '/blogfeed' do
route '/mp3feed' do
route '/opusfeed' do


You can find the blogging.rb and the Rules file on GitHub.

Flattr this!

Auftragsstatus bei Rakuten

Posted on 22. Juli 2015 Comments hat eine REST API, über die z.B. Aufträge abgefragt werden können. Die Doku gibt dazu folgende Auskunft:

pending = Bestellung ist neu eingegangen
editable = Bestellung ist zur Bearbeitung freigegeben
shipped = Bestellung ist versendet
payout = Bestellung ist ausbezahlt
cancelled = Bestellung ist storniert

Eine ausgiebiere Erklärung könnt so aussehen:

pending = Bestellung ist neu eingegangen. Wenn der Kunde über PayPal oder Kreditkarte bezahlt hat, wird dieser Zustand eigentlich sofort wieder verlassen. Eigentlich braucht man sich Aufträge mit diesem Status nicht angucken, weil im Normalfall Ware erst versandt wird, wenn sie auch bezahlt ist. Vorkasse Aufträge können z.B. länger in diesem Status verbleiben, eben so lange bis das Geld bei Rakuten eingegangen ist.
editable = Bestellung ist zur Bearbeitung freigegeben. Das heißt im Normalfall, dass der Kunde die Ware auch bezahlt hat. Diese Aufträge sollte man sich ins System holen, sie intern bearbeiten und kann dann in den nächsten Status springen
shipped = Bestellung ist versendet. Dies wird z.B. erreicht, indem eine Trackingnummer für das Paket eingegeben wird. Dies muss durch den Händler passieren, Rakuten wird diesen Status nie von alleine setzen.
payout = Bestellung ist ausbezahlt. Rakuten hat nach einer bestimmten Frist das aufsummierte Geld der Bestellungen (in der die aktuelle Bestellung enthalten ist) an den Händler überwiesen.
cancelled = Bestellung ist storniert. Der Kunde hat sich umentschieden oder der Händler hat die Bestellung storniert (etwa durch Fehlbestand)


Flattr this!

upload mit phpsec library und php

Posted on 22. Juli 2015 Comments

In der Doku, die gerade nicht verfügbar ist, da sie auf sourceforge liegt, ist ein Fehler. Der Upload via SFTP mit der phpseclib funktioniert auf 2 verschiedene Weisen folgendermaßen:

$sftp->put($destinationFilename, file_get_contents($sourceFullFilePath));


$sftp->put($destinationFilename, $sourceFullFilePath, NET_SFTP_LOCAL_FILE);


Flattr this!

Casinospiele im Internet – warum sie so beliebt sind

Posted on 22. Juli 2015

Das Internet hat in den letzten zwei Jahrzehnten einen beeindruckenden Siegeszug durch die Wohnzimmer und Büros der Menschen weltweit gehalten. War es erst nur ein Netz, in dem große Behörden und später Unternehmen gearbeitet haben, ist es inzwischen eine der meistgenutzten Art der Freizeitgestaltung geworden. Und das vor allem, wegen dem so vielfältigen Angebot, dass es zu bieten hat. Teil dieses Angebotes sind schon seit einigen Jahren Casino Spiele im Internet, wie sie bei zu sehen sind. Doch, warum erfreuen diese Online Casino Spiele  sich so einer Beliebtheit in Deutschland? Hier ein paar Hintergründe zur Szene der Online-Casinos und den Gründen für die Vorliebe der Deutschen für diese Form des Glücksspiels.

Das Online-Casino als Alternative – weil es hochwertig ist und einfach Spaß macht

Die Zeit, in der Anwendungen im Internet schleppend langsam liefen und von der Grafik her deutlich zu wünschen übrig ließen, ist inzwischen lange vorbei. Der Stand der Technik gibt es her, dass Online-Casinos nicht nur optisch bestechen, sondern auch von der Geschwindigkeit der Datenübertragung her ein absolutes Spielvergnügen bieten. Die Grafik die dabei zum Teil auf die Bildschirme der PC´s, Notebooks, Tablets oder Handys der Nutzer gezaubert wird, ist je nach technischem Stand des Casinos zwischen gut und sehr gut anzusiedeln.

Das Online-Casino ist immer, da wo du bist

Online-Casinos sind anders als klassische Casinos an festen Standorten letztlich stadortunabhängig. Der Spieler kann im Spielcasino online spielen, wo immer er möchte. Das bringt den großen Vorteil mit sich, dass man abends vor dem ins Bett gehen oder morgens zwischen Aufstehen und Arbeitsbeginn noch mal ein Spielchen absolvieren kann. Vielleicht auch in der Mittagspause auf dem Tablet eine willkommene Abwechslung? Wo auch immer du dich gerade aufhältst, dein Online-Casino ist immer bei dir, sobald du ein internetfähiges Gerät zur Hand hast. Selbst mit Öffnungszeiten von 0:00 Uhr – 23:00 Uhr können herkömmliche Casinos da eher nicht mithalten.

Das Online-Casino bietet eine Menge Extras, die es im reellen Casino nicht gibt

Viele Anbieter machen den Kunden den Einstieg mit Einstiegsbonusangeboten für die ersten Spiele einfacher. So kann der Spieler erste Erfahrungen sammeln, ohne dass es ihn reales Geld kostet, und kann dann selbst entscheiden, ob er weiterspielen möchte, sollte er das Startkapital verspielt haben. Außerdem gibt es bei den verschiedenen Anbietern zwischendurch immer mal wieder Bonusaktionen, mit denen man das Spielgeldkonto ein Stück weit erhöhen kann. Entsprechende Angebote kennen herkömmliche Casinos natürlich nicht. Hier zählt jeder Cent, sodass jeder verspielte Euro letztlich ein echter Euro ist – und der kann schon mal wehtun.

Die Gewinnchancen im Online-Casino stehen besser

Ob man es glaubt oder nicht, die Gewinnchancen in einem Online-Casino sind um ein Vielfaches besser, als in einem normalen Casino. Das liegt natürlich auch daran, dass die Kundenzahl eines Online-Casinos oftmals so groß ist, dass selbst bei einer größeren Gewinnchance für den Spieler am Ende für den Betreiber noch immer ein Reingewinn steht. Ausschüttungsquoten jenseits von 98 Prozent sind im Internet keine Seltenheit.

Die Gründe sind vielfältig, lassen sich aber im Endeffekt einfach zusammenfassen. Das Online-Casino ist der bequemere Spielort, es steht dem Spieler zu jeder Zeit zur Verfügung und letztlich ist die Geldsumme, die man hier wirklich verliert, oftmals kleiner, als wenn man in einem Casino irgendwo in Hamburg oder auf dem Land spielen würde.


Full disclosure: Dieser Beitrag wurde in Zusammenarbeit mit einem externen Partner erstellt.

Flattr this!

Domain von Domain Offensive bei Heroku nutzen

Posted on 24. Januar 2015 Comments

Ich habe neulich die Domain bei Domain Offensive erworben und wollte nun diese Domain mit meiner Heroku App für Morsecode As A Service nutzen. Allerdings bietet Heroku nicht die Möglichkeit an, A Resource Records oder AAAA Resource Records (für IPv6) zu benutzen. Stattdessen empfehlen sie einen CNAME Record. Nun ist es von der IETF aber nicht empfohlen bzw. gegen den Standard CNAME Records für root Domain Namen zu verwenden und viele Hoster unterstützen dies auch nicht. Wie der Name schon andeutet sind diese Einträge für weitere anerkannte Namen der selben Domain gedacht (z.B. .net und .com für denselben Namen).

Der Workaround funktioniert bei also folgendermaßen:

  1. In den Domaineinstellungen wird eine Weiterleitung eingerichtet auf
  2. Nach einer Weile ist es möglich unter DNS (Zonen Details), die A bzw. AAAA Resource Records für * zu entfernen
  3. Außerdem muss man einen CNAME Eintrag für anlegen, der auf zeigt.

Der Ablauf ist dann folgender:

  1. Eine DNS Anfrage auf wird gestellt
  2. Der DNS Server liefert einen A bzw. AAAA Resource Record für einen lighttpd Server von Domain Offensive zurück
  3. Dieser liefert dem Client eine HTTP Redirect 301 Message auf zurück (s. 1. weiter oben)
  4. Eine DNS Anfrage auf gestellt
  5. Auf diese antwortet ebenfalls mit einem CNAME Eintrag auf
  6. Die HTTP Anfrage wird an gestellt.

Löscht man auch die A bzw. AAAA Resource Records, funktioniert die Domain nur über die Subdomain

Dies funktioniert nur für Webservices unter Port 80 via HTTP. Für andere Bereiche bleibt wohl nur übrig, auch die A bzw. AAAA Records auf zu löschen und in den Anfragen nur die Subdomain zu benutzen.

Ausprobieren kann man das nach ein bisschen Wartezeit mit z.B. cURL:

$ curl -vL
$ curl -vL

Bei meinem Beispiel sieht das wie folgt aus:


$ curl -vL
* Hostname was NOT found in DNS cache
*   Trying
* Connected to ( port 80 (#0)
> GET /encode/A HTTP/1.1
> User-Agent: curl/7.35.0
> Host:
> Accept: */*
< HTTP/1.1 301 Moved Permanently
< Location:
< Content-Length: 0
< Date: Sat, 24 Jan 2015 20:09:09 GMT
* Server lighttpd/1.4.28 is not blacklisted
< Server: lighttpd/1.4.28
* Connection #0 to host left intact
* Issue another request to this URL: ''
* Hostname was NOT found in DNS cache
*   Trying
* Connected to ( port 80 (#1)
> GET /encode/A HTTP/1.1
> User-Agent: curl/7.35.0
> Host:
> Accept: */*
< HTTP/1.1 200 OK
* Server Cowboy is not blacklisted
< Server: Cowboy
< Connection: keep-alive
< Content-Type: application/json
< Content-Length: 34
< Date: Sat, 24 Jan 2015 20:09:09 GMT
< Via: 1.1 vegur
* Connection #1 to host left intact

Flattr this!

Morsecode As A Service: node.js app with restify and Heroku

Posted on 22. Januar 2015 Comments

I wanted to play around with node.js and REST APIs. Heroku is widely used for deploying node.js app, last but not least because they give you one free instance to test your code and the possibility to use your own domain name (via CNAME).

Until now the code is rather trivial. This for example is the encode function (plaintext->morsecode). It uses the npm module morse to encode the given string in the request parameters and returns it with the plaintext in an array. The requests are handled by restify.
function encode(req, res, next) {
var answer = {}
answer.plaintext = req.params.string.toUpperString();
answer.morsecode = morse.encode(req.params.string);

This function gets called later here.
server.get('/encode/:string', app.encode);

This starts the server on the port from the Heroku instance.
var port = process.env.PORT || 8080;
server.listen(port, function() {
console.log('%s listening at %s',, server.url);

The decode function is equivalent, except that I test if there are only „.“, „-“ and white spaces in the request.

I wrote the documentation with the automatic page generator from GitHub Pages in the repository and so with the following code the user is redirected there when entering the root „/“.


function redirectToDocumentation(req,res,next) {
res.send(302, null, {
Location: API_DOKU

It’s reachable under or

Flattr this!

Skript mit cat, unzip, grep und awk für eBays XML Responses

Posted on 7. Januar 2015 Comments

Wenn man bei eBay per API z.B. ein FixedPriceItem hinzufügt bekommt man die folgende Antwort nachdem der Prozess erst Scheduled und dann InProcess ist:

Status is Completed
Downloading fixed price item responses...Done
File downloaded to /tmp/
Unzip this file to obtain the fixed price item responses.

Den folgenden Code eine Datei schrieben, dann in /usr/local/bin verschieben und mit chmod +x Ausführrechte geben.

cat `unzip -o $1 | grep inflating |awk '{print $2}'`

Mit diesem Skript bekommt man zum debuggen eine schnelle Ausgabe der XML aus der Konsole bewirken:

debugebayxml /tmp/

Flattr this!

Using a Perl script because refactoring of a project with Android tools didn’t work

Posted on 20. Dezember 2014 Comments

I wanted to rename my project but I guess since it has a lot of dependencies that caused an error somewhere and I got the error message:

A fatal error occurred while performing the refactoring.
An unexpected exception occurred while creating a change object. See the error log for more details.

So I just the normal refactoring feature of Eclipse which not surprisingly also caused an error. After editing the AndroidManifest package entry, the import of the resources in the sources files didn’t work. It still said

import com.example.oldpackage.R

Only a couple of resource files needed manual editing but the Java files were a problem. What did the trick for me was this one-liner

perl -pi -w -e 's/import com.example.oldpackage.R/import com.example.newpackage.R/g;' `grep -r -l "import com.example.oldpackage.R"`

I realise this is rather quick&dirty (do a backup 😉 ) but it did work for this project. A short explanation:


  • -pi puts the code in a loop (like -n, but sed-style)
  • -w gives you warnings
  • -e is one line of programm and since -pi
  • /g global, for all lines in the file


  • -r recursive
  • -l give out files that matches the following search string

Flattr this!