[Solved]: Compare file date of Android and FTP

Want to talk about something that isn't covered by another category?

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
AxWald
Posts: 578
Joined: Thu Mar 06, 2014 2:57 pm

[Solved]: Compare file date of Android and FTP

Post by AxWald » Fri Jan 06, 2017 2:34 pm

Edit notice: Title was changed from: "Help with Regex/ PHP, please!"

Hi,

due to LC's subterranean implementation for Android I need to go rough roads to accomplish my goals.

Here I need a detailed listing of a ftp-folders contents, which usually is easy:

Code: Select all

put "ftp://" & myUSR & ":" & myPAS \
         & "@" & myDir into myURL
   put URL myURL into myVar
or, with more meaningful results:

Code: Select all

put "ftp://" & myUSR & ":" & myPAS \
         & "@" & myDir into myURL
   libURLSetFTPListCommand "LIST" 
   put URL myURL into myVar
On Android, this simply isn't implemented yet :/

So I have to call PHP(!) to help, to get my detailed folder list. Found some basic code, but I'm running into a problem. Lemme show you:

Code: Select all

$ret = ftp_raw($ftp, 'PASV');  
     // $ret[0] => "227 Entering Passive Mode (127,0,0,1,196,66)." //
if (preg_match('#^227.*\(([0-9]+,[0-9]+,[0-9]+,[0-9]+),([0-9]+),([0-9]+)\)$#', $ret[0], $matches)) {
     $controlIP = str_replace(',', '.', $matches[1]);
     $controlPort = intval($matches[2])*256+intval($matches[3]);
     $socket = fsockopen($controlIP, $controlPort);
     ftp_raw($ftp, 'MLSD');
     // $socket is needed in the following code //
The "ftp_raw" sets mode to passive, and provides an array, whose later used key value I have included.
If I understand it correctly, "127,0,0,1,196,66" should then be extracted, so that the following lines would resolve to:

Code: Select all

     $controlIP = '127.0.0.1';
     $controlPort = (196*256+66);
     $socket = fsockopen('127.0.0.1',50242);
But the "preg_match", that should test the regex:
"#^227.*\(([0-9]+,[0-9]+,[0-9]+,[0-9]+),([0-9]+),([0-9]+)\)$#"
against the string:
"227 Entering Passive Mode (127,0,0,1,196,66)."
fails with no hit.
I found a second version, with "/" instead of "#" at begin and end, but both versions never hit.

Now my knowledge of Regexp is even less than my knowledge of PHP, so you can understand I'm doomed.
Is any kind soul out there that can:
  1. Find the mistake in the regexp & correct it, OR
  2. Give me a hint what PHP construction I should google for to solve the problem in another way?
Thx a lot, have fun!

PS:
There's a solution, but it's not really satisfying:

Code: Select all

ftp_rawlist($ftpConn, '/');
This works exactly as the first LC example above, but both give dateTime in a poor manner: "Jan 6 06:01". Not really useful without year.
Last edited by AxWald on Mon Feb 20, 2017 11:26 am, edited 1 time in total.
All code published by me here was created with Community Editions of LC (thus is GPLv3).
If you use it in closed source projects, or for the Apple AppStore, or with XCode
you'll violate some license terms - read your relevant EULAs & Licenses!

Lagi Pittas
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 365
Joined: Mon Jun 10, 2013 1:32 pm

Re: Help with Regex/ PHP, please!

Post by Lagi Pittas » Fri Feb 17, 2017 3:04 pm

Hi Axwald

Hope I'm not teaching my granny to suck eggs but here goes ...

ftp_Rawlist() works in a brain dead way - what were they thinking it's more code to create it and more code to decipher the results, a lose/lose.

Basically as I understand it If the File was created in the current year you get the time returned but not the year, and if the creation date was in the last year you don't get the time but get the year.

You could say you are really only interested in the times for files created in the current year if it's to do with backups etc.

Since the year replaces the time you can just check for a colon and if it's not there you know it's a year.

Regards Lagi

AxWald
Posts: 578
Joined: Thu Mar 06, 2014 2:57 pm

[Solved]: Compare file date of Android and FTP

Post by AxWald » Mon Feb 20, 2017 11:24 am

Oooops!

Actually I forgot about this already ;-)
Lagi Pittas wrote:ftp_Rawlist() works in a brain dead way - what were they thinking it's more code to create it and more code to decipher the results, a lose/lose.
Right, it's a PITA. And worse, LC's "put URL myFTPDirectoryURL" gives the same crap as result. With the icing of the cake of not working on Android at all where I need it ...

I wanted to document my solution anyways, so here we go:

What I wanted to do was only to check if a local file (of an Android app) is outdated and if it is, downloading the fresh version from the FTP. To do this I now use a .php script (one in each directory, they need the directory name in the script ...). Since having login data in a PHP script gives me bad feelings, I use a special ftp User that can't do anything but "list" the semi-public directory part only.

The PHP script:

Code: Select all

<?php
$c = ftp_connect('localhost');
ftp_login($c, 'USER', 'PASSWORD');
$data = ftp_rawlist($c, '/DIRECTORY');
print_r($data);
?>
PHP output (be sure to have correct USER, PASSWORD and DIRECTORY in the script):

Code: Select all

Array
(
    [0] => drwxr-xr-x   2 xxxxXXXX yyyyYYYY     4096 Feb 18 00:35 .
    [1] => drwxr-xr-x   7 xxxxXXXX yyyyYYYY     4096 Feb  5 10:25 ..
    [2] => -rw-r--r--   1 xxxxXXXX yyyyYYYY    84754 Feb 16 16:14 MM_Ordermaker.rev
    [3] => -rw-r--r--   1 xxxxXXXX yyyyYYYY    30093 Feb  6 12:51 ckommprint.rev
    [3] => -rw-r--r--   1 xxxxXXXX yyyyYYYY      139 Feb  5 10:27 fLIST.php
)
To compare, the LC version "put URL myFTPDirectoryURL", if invoked in a supported environment, returns that:

Code: Select all

drwxr-xr-x   2 xxxxXXXX yyyyYYYY     4096 Feb 18 00:35 .

drwxr-xr-x   7 xxxxXXXX yyyyYYYY     4096 Feb  5 10:25 ..

-rw-r--r--   1 xxxxXXXX yyyyYYYY    84754 Feb 16 16:14 MM_Ordermaker.rev

-rw-r--r--   1 xxxxXXXX yyyyYYYY    30093 Feb  6 12:51 ckommprint.rev

-rw-r--r--   1 xxxxXXXX yyyyYYYY      139 Feb  5 10:27 fLIST.php
Obviously both are the output of the same unixoid shell command, just wrapped differently.

Additional difficulty:
Since I want to compare to local files I want to use "the detailed files" too, that gives a quite different output:

Code: Select all

ckommprint.rev,30093,,1486384526,1486402901,1486405661,,,,666,
MM_Ordermaker.rev,84754,,1486715345,1487257875,1487268402,,,,666
So the function takes, as input, either above .PHP output, or the output of the above "detailed files" call, with "true" as parameter "isLocal":

Code: Select all

function clearLIST myData, isLocal      -- Goal: to get nice dir listings
   
   if not isLocal then                                   --  this is the output of the .php call
      delete line 1 to 2 of myData
      delete last line of myData
      repeat until offset("  ", myData) = 0      --  at first, kill double spaces in the data
         replace "  " with " " in myData            --  might not be neccessary, but in any case ...
      end repeat
      
      convert the date to dateitems
      put char 1 to 4 of it into myYear            -- the current year to use as dummy
      set itemdel to space                              -- a suitable delimiter
      
      repeat for each line myLine in myData
         delete char 1 to (offset(">",myLine)+12) of myLine                         --  removing junk
         if (char 1 of myLine <> "1") OR (myLine = empty) then next repeat  -- ignore all but files
         convert "Mon, " & item -3 of myLine & " " & item -4 of myLine & " " & \
               myYear & " 00:00:00 +0000" from internet date to dateitems     --  date magick :)
         put char 6 to (offset(comma,it,8)+7) of it into fileDate
         replace comma with "-" in fileDate      --  now we have a nice, comparable SQL date fragment :)
         put (item -1 of myLine & tab &  item -5 of myLine & tab & \
               fileDate & CR) after myVar          --  creating output variable
      end repeat
      
   else                                                          --  This is the result of a "detailed files" call
      set itemdel to comma
      repeat for each line myLine in myData
         get item 5 of myLine
         convert it from seconds to dateitems
         put char 6 to (offset(comma,it,8)+7) of it into fileDate
         replace comma with "-" in fileDate   --  now we have a nice, comparable SQL date fragment :)
         put (item 1 of myLine & tab & item 2 of myLine & tab & \
               fileDate & CR) after myVar  --  creating output variable
      end repeat
   end if
   
   delete last char of myVar  --  cleaning up
   return myVar  --  done:
   --  output:  {fList2.php	201	1-6}   //  Filename tab ByteSize tab DatePart return
end clearLIST
The output looks like this:

Code: Select all

 --  .PHP output:
MM_Ordermaker.rev	84754	2-16
ckommprint.rev	30093	2-6
fLIST.php	139	2-5

 --  "detailed files" output:
ckommprint.rev	30093	2-6
MM_Ordermaker.rev	84754	2-16
Now I can compare. Using this construction:

Code: Select all

   set the defaultfolder to gPath
   put clearlist(the detailed files,true) into myLocList  --  load LISTs to compare if new stuff to dl'
   put clearLIST(URL ("http://WhereEver.biz/MM_Setup/" & UserDir & "/fLIST.php")) into myRemList
...
      put line lineoffset(item i of myFile & ".rev",myLocList) of myLocList into myLoc
      put line lineoffset(item i of myFile & ".rev",myRemList)of myRemList into myRem
...
   if ((item 2 of myLoc <> item 2 of myRem) OR \  -- size is different?
      (item 3 of of myRem > item 3 of of myLoc)) then   --  remote file is newer?
I determine what to replace. Works sufficiently well - after all there's rarely a file change w/o a change in the byte size.
Lagi Pittas wrote:Basically as I understand it If the File was created in the current year you get the time returned but not the year, and if the creation date was in the last year you don't get the time but get the year.
Oops. Canned madness, family pack. Anyways, I ignore this time/ year fragment already ;-))

Took me a lot of hair pulling, this. Especially the testing on the Android device (my first real Android job) where I had to find out the hard way how poor LCs Android implementation actually is :/

Anyways. I changed the subject, may this save some poor Android dev some trouble, some day!

Have fun!

Edit: Maybe a Mod can push this over to the Android section where it would suit better? Thx!
All code published by me here was created with Community Editions of LC (thus is GPLv3).
If you use it in closed source projects, or for the Apple AppStore, or with XCode
you'll violate some license terms - read your relevant EULAs & Licenses!

Lagi Pittas
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 365
Joined: Mon Jun 10, 2013 1:32 pm

Re: [Solved]: Compare file date of Android and FTP

Post by Lagi Pittas » Mon Feb 20, 2017 2:13 pm

Thanks Axwald

That's what I like about this forum - you've solved a problem for me that I haven't got .... yet!!! but I don't doubt I will have.
Although I havea n android app that saves and loads from a server but I cheated and used LC server using Hostm.com - I'm lazy and can't be bothered to install the server.


Regards lagi

Post Reply

Return to “Off-Topic”