Entries tagged timeout

Automate selling at LaRedoute #1: Get new orders

Posted on 16. Dezember 2014 Comments

This blog post is part of the series Automize selling at LaRedoute.


The french marketplace LaRedoute unfortunately doesn’t have a real API, but they do have ways to automize some processes. A lot of smaller marketplaces have this concept as well. You will get credentials for an SFTP server. On this server you will find the folders ToSupplier and FromSupplier, where the „supplier“ (aka you) can up- and download a range files documented by Merchantry in their blog. The processing of the uploaded files can take up to 6 hours, but is sometimes done in only a couple of minutes, so I’m going to assume the worst case of 6 hours in this post.

While programming a couple of scripts I found the following problems:

  • the server is incredibly slow sometimes (better at nights), so sometimes the connections just time out
  • sometimes the listing for the ToSupplier folder times out because there are too many files (according to support…huh?), so they have to be deleted regularly
  • not only the connection to LaRedoute but also the connection to my local MySQL server times out
  • I have to reserve a purchased item once I accepted it on LaRedoute immediately, because it could be sold elsewhere in the 6 hours LaRedoute might take to give me the shipping address

New orders can be found in the ToSupplier folder in tab seperated CSV files (but .txt ending) with the format OrdersYYYY-MM-DD-hh-mm-ss.txt.

Since PHP is the companies main language I will show a couple of scripts which automize downloading and processing those files. The code is of course simplified for better understanding. We’re using SFTP instead of FTP and I found using the phpseclib to be the most usable library.

I will propose the use of 2 Tables in the MySQL database: TEMP-FILENAMES and FILENAMES-HISTORY. Both have a the unique column filename. FILENAMES-HISTORY will contain the name of every file ever processed by the following script, TEMP-FILENAMES is a helper table that will be truncated after every run.

First, we need to establish a connection


$sftp = new Net_SFTP(SFTP_LAREDOUTE_HOST);
if (!$sftp->login(SFTP_LAREDOUTE_USER, SFTP_LAREDOUTE_PASS)) {
exit('Login Failed');
}

Then we change directory. This is a command that usually involves listing the directory changed into, but since this is not a graphical client, the real timeout might come on line below. $nlist will just be null if the listing fails, and I will assume it didn’t work if it takes more than 30 seconds.

$sftp->chdir('/ToSupplier');

$beforetime = time();
$nlist = $sftp->nlist();
$aftertime = time();
if(($aftertime-$beforetime) > 30 ) {
exit('Timeout while Listing directory');
}

The next piece of code is only executed if the listing worked. Every filename that includes the word „Order“ is now inserted into the temporary table:

foreach($nlist as $filename) {
if (strpos($filename, 'Order') !== false) {
$qry = "INSERT INTO `TEMP-FILENAMES`(`filename`) VALUES ('". $filename . "')";
$insert = mysql_query($qry,MYSQLCONNECTION) or print mysql_error();
}
}

You can look at the difference between the filenames in your HISTORY table and the possibly new ones in the temporary table.

$tmpCmpFilenames = array();
$qry = "SELECT `filename` FROM `TEMP-FILENAMES` WHERE `filename` NOT IN (SELECT `filename` FROM `FILENAMES-HISTORY`)";
$select = mysql_query($qry, MYSQLCONNECTION) or print mysql_error();
while ($row = mysql_fetch_assoc($select)) {
$tmpCmpFilenames[] = $row['filename-id'];
}

Now we have all the new files in the array $tmpCmpFilenames. The correct way would be make sure the downloaded files are correct with hashes. Instead we decided to misuse the filesize, since it’s a good indicator something didn’t work properly;) The files not downloaded correctly are deleted from the array. They will appear next time the script is run.

foreach($tmpCmpFilenames as $filename) {
$remotefilesize = $sftp->size($filename);
$sftp->get($filename, 'OrdersFromLaRedoute/' . $filename);
$localfilesize = filesize('OrdersFromLaRedoute/' . $filename);
if ($remotefilesize != $localfilesize) {
unset($tmpCmpFilenames[$filename]);
}
}

We can now insert the filenames into the HISTORY table.

foreach($tmpCmpFilenames as $filename) {
$qry = "INSERT INTO `FILENAMES-HISTORY`(`filename`) VALUES ('". $filename . "')";
$insert = mysql_query($qry, MYSQLCONNECTION) or print mysql_error();
}

Last but not least, the temporary table needs to be truncated for the next run.

$truncate=mysql_query("TRUNCATE TABLE `TEMP-FILENAMES`",MYSQLCONNECTION) or print mysql_error();

The next step is described in part 2 of this series.

Automatisches Ausloggen im Kiosk Modus bei Inaktivitaet mithilfe von xscreensaver

Posted on 11. April 2013 Comments

Das Problem bei Rechnern im Kiosk Modus ist, dass die Benutzer sich manchmal nicht ausloggen und so prinzipiell jeder, der sich als nĂ€chstes an den Rechner setzt einfach diverse Accounts ĂŒbernehmen kann, weil z.B. die Cookies noch vorhanden sind. Dieser Artikel basiert auf dem vorherigen Raspberry Pi als Kiosk mit resourcenschonendem Browser und VESA Mount. Da dieser Brower sich neu startet, wenn der Prozess mit 5 Sekunden Pause nicht lĂ€uft, kann man ihn einfach killen.

Zur Messen der InaktivitÀt haben sich die Leute vom xscreensaver-Projekt schon genug Gedanken gemacht, also möchte ich das hier nutzen, statt etwas eigenes zu schrieben oder timeoutd zu nutzen. Die Timeout Zeit setzt man in ~/.xscreensaver.

In den man-pages von xscreensaver-command findet man folgendes Perl-Skript. Ich habe es ein bisschen meinen Anforderungen angepasst. Perl muss natĂŒrlich vorher installiert werden.

sudo apt-get install perl

Es piped in der Variable IN den Befehl xscreensaver-command -watch, welcher den xscreensaver beobachtet. Sollte dort nun also die Meldung BLANK(Bildschirmschoner geht an) oder LOCK(Bildschirmschoner lockt) auftauchen(passiert nach der eben definierten Zeit), dann deaktiviert er ihn sofort wieder, killt den Browser und setzt ein flag. Das wiederrum löst UNBLANK aus(Bildschirmschoner geht aus) und das flag wird zurĂŒckgesetzt, da er sonst im nĂ€chsten Schleifendurchlauf sofort wieder den Browser killen wĂŒrde. Durch das Skript aus dem eben genannten Artikel prĂŒft der Rechner sowieso, ob der Browser lĂ€uft und wenn nicht, startet den Prozess. Damit wird nach spĂ€testens 5 Sekunden der Browser neu gestartet und man muss ihn hier nicht starten. Die Datei habe ich xscreensaver-command.pl genannt, nach /usr/local/bin geschoben und in den Autostart in .xsession eingetragen.

Code (Download)

 

my $blanked = 0;
open (IN, "xscreensaver-command -watch  |");
while(<IN>) {
        if (m/^(BLANK|LOCK)/) {
                if (!$blanked) {
                        # Schliesse Browser
                        # Starte Browser neu
                        print "Deaktiviere xscreensaver...\n";
                        system "xscreensaver-command -deactivate";
                        print "Beende Browser...\n";
                        system "killall browser-repat";
                        print "In 5 Sekunden wird der Browser neu gestartet";
                        $blanked = 1;
                 }
        } elsif (m/^UNBLANK/) {
                $blanked = 0;
        }
}