Page 1 of 2

How to read the contents of a folder on a web server via ftp

Posted: Thu Apr 27, 2017 8:21 am
by Eugene Lutsenko
How to read the contents of a folder on a web server via ftp?
I'm using the following program:

Code: Select all

      mApplName = "Applications-"+STRTRAN(STR(VAL(ALLTRIM(WebAppls->Num_Appl)),6),' ','0')
   
      cGDServer:="ftp://j90540lw.beget.tech"                                                                                      
                                                                                                                                  
      oFtp := XbFTPClient():new()                                                                                                 
                                                                                                                                  
      IF oFtp:Connect(cGDServer)                          // Соединение                                                           
         IF oFtp:Login(Ftp_User, Ftp_Passw)               // Авторизация                                                          
                                                                                                                                  
            **** Сделать текущей папку приложения: ftp://j90540lw.beget.tech/aidos/public_html/                                              
*                                                  ftp://j90540lw.beget.tech/Source_data_applications/'+mApplName
                                                                                                                                  
            if ! oFtp:SetCurrentDirectory("aidos/public_html/")                                                                   
*           if ! oFtp:SetCurrentDirectory('aidos/public_html/Source_data_applications/'+mApplName)                                                                   
               LB_Warning('Не удалось сделать текущей директорию: "aidos/public_html/Source_data_applications/'+mApplName+'"', '(C) Система "Эйдос-Х++"' )              
               RETURN NIL                                                                                                         
            endif                                                                                                                 
                                                                                                                                  
            oFtp:PassiveMode:=.T.                         // Пассивный режим                                                      

            PUBLIC aDir := oFtp:Directory()               // Борис Борзик, для этого нужен только FTP, т.к. под HTTP не работает oHttp:Directory()
 
*           DC_DebugQout(aDir)

*           Thread():new():start({||GuiBrowse(aDir)})     // Отображение массива с данными о файлах директории на FTP-сервере (для отладки, как в browtest.prg)
[/size]
(Boris Borzic is the CTO & President of Xb2.NET Inc. http://www.xb2.net).

To display the folder contents I use the example from Roger:

Code: Select all

FUNCTION GuiBrowse()

   LOCAL GetList[0], oBrowse, bColorSize, bColorDate

*  bColorSize := {|n|n:=DC_GetColArray(2,oBrowse),IIF(n>10000 ,{nil,GRA_CLR_GREEN},{nil,GRA_CLR_YELLOW})}
   bColorDate := {|d|d:=DC_GetColArray(7,oBrowse),IIF(d=Date(),{nil,GRA_CLR_BROWN},{nil,GRA_CLR_PINK})}

   @ 0,0 DCBROWSE oBrowse DATA aDir ;
         PRESENTATION DC_BrowPres() ;
         SIZE 100, 20 FIT ;
         HEADLINES 2 ;
         FONT '8.Lucida Console' ;
         COLOR {||IIF(oBrowse:arrayElement%2==0,nil,{nil,GraMakeRGBColor({230,252,213})})}          // Вывод поля цветом RGB
   
   DCBROWSECOL ELEMENT  1 HEADER 'F1' WIDTH 13 PARENT oBrowse
*  DCBROWSECOL ELEMENT  2 HEADER 'F2' WIDTH 10 PARENT oBrowse COLOR bColorSize
   DCBROWSECOL ELEMENT  2 HEADER 'F2' WIDTH 10 PARENT oBrowse
   DCBROWSECOL ELEMENT  3 HEADER 'F3' WIDTH 10 PARENT oBrowse
   DCBROWSECOL ELEMENT  4 HEADER 'F4' WIDTH 10 PARENT oBrowse
   DCBROWSECOL ELEMENT  5 HEADER 'F5' WIDTH  3 PARENT oBrowse
   DCBROWSECOL ELEMENT  6 HEADER 'F6' WIDTH  3 PARENT oBrowse PICTURE '9'
*  DCBROWSECOL ELEMENT  7 HEADER 'F7' WIDTH 10 PARENT oBrowse COLOR bColorDate
   DCBROWSECOL ELEMENT  7 HEADER 'F7' WIDTH 10 PARENT oBrowse
   DCBROWSECOL ELEMENT  8 HEADER 'F8' WIDTH 10 PARENT oBrowse
   DCBROWSECOL ELEMENT  9 HEADER 'F9' WIDTH 10 PARENT oBrowse
   DCBROWSECOL ELEMENT 10 HEADER 'F10' WIDTH 10 PARENT oBrowse

   DCREAD GUI FIT TITLE 'Browse Test'

ReTURN nil
[/size]
(Roger Donnay)

Example Roger works well on the array, which is formed locally (aDir := Directory() ). But if you use an array containing information about the files in the folder on the web server (aDir := oFtp:Directory() ), it turns out that something is not right:

Re: How to read the contents of a folder on a web server via

Posted: Thu Apr 27, 2017 11:13 am
by rdonnay
I need to know what is the structure of the array returned by oFtp:directory().
It seems as though it is not a simple 2-dimensional array.

Do this:

aDirectory := oFtp:directory()

DC_ASave( aDirectory, 'DIRECTORY.AR' )

Attach the DIRECTORY.AR file to this message thread so I can download it and see its structure.

Re: How to read the contents of a folder on a web server via

Posted: Thu Apr 27, 2017 12:08 pm
by Eugene Lutsenko
I also guessed that the array is not a standard for directories, but what he has not understood

http://j90540lw.beget.tech/AidosAstraX/DIRECTORY.AR

Re: How to read the contents of a folder on a web server via

Posted: Thu Apr 27, 2017 4:07 pm
by rdonnay
That's what I thought.
The array is a single-dimension array of long character strings.
Here is a simple bit of code to view the information.
It converts the array to a 2-dimensional array because that is a requirement for DCBROWSE.

If you need separate columns for the data, that will require parsing out the information and that is a little more work.

Code: Select all

aDir := DC_Arestore('directory.ar')
FOR i := 1 TO Len(aDir)
  aDir[i] := { aDir[i] }
NEXT

@ 0,0 DCBROWSE oBrowse DATA aDir SIZE 50,20 FIT FONT '12.Lucida Console'

DCBROWSECOL ELEMENT 1 HEADER 'File Directory' PARENT oBrowse WIDTH 100

DCREAD GUI FIT 

Re: How to read the contents of a folder on a web server via

Posted: Thu Apr 27, 2017 7:52 pm
by Cliff Wiernik
Yes, the ftp directory display returned by xb2net is just the simple strings. You need to be concerned though about the content of the strings. Not every FTP server returns the directory listing in the exact same format. So you need to know what you intended FTP server returns. We were working with the FTP server from our ISP and then the FTP from our SLES linux distribution which I think is PureFTP and they were slightly different. Since I could be connecting to one or the other using the same basic code, I needed to detect the markers as to the format and then could parse each one appropriately.

Re: How to read the contents of a folder on a web server via

Posted: Thu Apr 27, 2017 10:14 pm
by Eugene Lutsenko
Hey, Roger! Hey, Cliff!

Thank you. I understand. In principle, now I don't need detailed information about the files, which gives a function: oFtp:Directory(). Moreover, different servers can distinguish the Xia in the structure of this information. Now I only need the file names in a given directory quite certain (my) web server. So that is enough. This is the solution to my problem. And this solution is as always simple and effective in famous brilliant style Roger. Thank you again!!!

Re: How to read the contents of a folder on a web server via

Posted: Sat Apr 29, 2017 2:00 pm
by Eugene Lutsenko
In General, thanks to Your help, did what you wanted. Determined on FTP what files there are in a given directory on a WEB server and downloaded them via FTP to your local computer. But left two questions (roughness).

First, for some reason the file from the WEB server not downloaded to the current folder on the local computer, and one in which is located the executable modules of the system (oFtp:GetFile(mFileName, mFileName)). I would like to once they are downloaded into the same directory in which you want. We have then just copy these files from the directory system in the correct directory, and then delete them in the directory with the system.

Second, when I clean them, for some reason, on some file the uninstall process hangs. I had the impression that this is some kind of cache problem. After all these files have just been downloaded from the Internet and possibly not yet written from the cache to the hard drive. Appropriately there is a second question: how do I force the cache to be stored to the hard drive from the program in Alaska?

Below is the code snippet of the program, who does it all:

Code: Select all

      cGDServer:="ftp://j90540lw.beget.tech"                                                                                      
                                                                                                                                  
      oFtp := XbFTPClient():new()                                                                                                 
                                                                                                                                  
      IF oFtp:Connect(cGDServer)                          // Соединение                                                           
         IF oFtp:Login(Ftp_User, Ftp_Passw)               // Авторизация                                                          
                                                                                                                                  
            **** Сделать текущей папку приложения: ftp://j90540lw.beget.tech/aidos/public_html/                                              
*                                                  ftp://j90540lw.beget.tech/Source_data_applications/'+mApplName
                                                                                                                                  
*           if ! oFtp:SetCurrentDirectory("aidos/public_html/")                                                                   
            if ! oFtp:SetCurrentDirectory('aidos/public_html/Source_data_applications/'+mApplName)                                                                   
               LB_Warning('Не удалось сделать текущей директорию: "aidos/public_html/Source_data_applications/'+mApplName+'"', '(C) Система "Эйдос-Х++"' )              
               RETURN NIL                                                                                                         
            endif                                                                                                                 
                                                                                                                                  
            oFtp:PassiveMode:=.T.                         // Пассивный режим                                                      

            PUBLIC aDir := oFtp:Directory()               // Борис Борзик, для этого нужен только FTP, т.к. под HTTP не работает oHttp:Directory()

            **** Просмотр массива директории с FTP-сервера от Роджера

            aDirectory := {}
            FOR i := 1 TO Len(aDir)
                AADD(aDirectory, ALLTRIM(aDir[i]))
                aDir[i] := { ConvToOemCP(aDir[i]) }
            NEXT
            @ 0,0 DCBROWSE oBrowse DATA aDir SIZE 50,30 FIT FONT '10.Lucida Console'
            DCBROWSECOL ELEMENT 1 HEADER 'Файлы приложения N:'+ALLTRIM(STR(mRecno))+'-"'+ALLTRIM(WebAppls->Appl_Name)+'"' PARENT oBrowse WIDTH 53
            DCREAD GUI FIT
*           DCMsgBox 'Two Windows should be showing:', ;
*                    '(1) A Gui Browse in a Dialog Window', ;
*                    '(2) A HTML Browse in a Web Browser'

            *** Имя файла всегда последнее в строке, искать его справа налево до ":"
            *** Отличать имена файлов от имен папок, использовать только имена файлов

*           oScrn   := DC_WaitOn( 'Загрузка файлов приложения N:'+ALLTRIM(STR(mRecno))+'-"'+ALLTRIM(WebAppls->Appl_Name)+'" с FTP-сервера.' )

            aFileName := {}

            FOR j=1 TO LEN(aDir)

                mPos = AT(':',aDirectory[j])
                mFileName = SUBSTR(aDirectory[j],mPos+4,LEN(aDirectory[j])-mPos-3)

                oScrn   := DC_WaitOn( 'Загрузка приложения: "'+ALLTRIM(WebAppls->Appl_Name)+'" с FTP-сервера. Файл: '+ALLTRIM(STR(j))+'/'+ALLTRIM(STR(LEN(aDir)))+'-"'+ConvToOemCP(mFileName)+'"' )
                IF oFtp:GetFile(mFileName, mFileName)
                   AADD(aFileName, mFileName)
*                  LB_Warning('Загрузка файла: '+ALLTRIM(STR(j))+'/'+ALLTRIM(STR(LEN(aDir)))+'-"'+ConvToOemCP(mFileName)+'" с FTP-сервера системы "Эйдос" завершена успешно', '(C) Система "Эйдос-Х++"' )             
                ENDIF
                DC_Impl(oScrn)                
            NEXT                                                                                                  
*           DC_Impl(oScrn)                                                                                                                       

         ELSE                                                                                                                     
            LB_Warning('Нет авторизации на FTP-сервере', '(C) Система "Эйдос-Х++"')                                               
            RETURN NIL                                                                                                            
         ENDIF                                                                                                                    
      ELSE                                                                                                                        
         LB_Warning('Нет соединения с FTP-сервером', '(C) Система "Эйдос-Х++"')                                                   
         RETURN NIL                                                                                                               
      ENDIF                                                                                                                       

*     DC_Impl(oScrn)  

      *** Перенос файлов приложения из папки с исполнимым модулем системы "Эйдос" в папку Inp_data

      DIRCHANGE(Disk_dir)                 // Перейти в папку с системой

      FOR j=1 TO LEN(aFileName)
          Name_SS = aFileName[j]
          Name_DD = Disk_dir+"\AID_DATA\Inp_data\"+aFileName[j]
          COPY FILE (Name_SS) TO (Name_DD)
      NEXT
*     FOR j=1 TO LEN(aFileName)
*         IF FILE(aFileName[j])
**           ERASE(aFileName[j])
*            DELETE FILE (aFileName[j])
*         ENDIF
*     NEXT
[/size]

В общем, благодаря Вашей помощи, сделал то, что хотел. Определил по FTP какие файлы есть в заданной директории на WEB-сервере и скачал их по FTP на локальный компьютер (oFtp:GetFile(mFileName, mFileName)). Но при этом осталось два вопроса (шероховатости). Во-первых, почему-то файлы с WEB-сервера скачиваются не в текущую папку на локальном компьютере, а в ту, в которой находится исполнимый модуль системы. Хотелось бы, чтобы они сразу скачивались в ту директорию, в которую нужно. Приходится потом просто копировать эти файлы из директории с системой в нужную директорию, а потом удалять их в директории с системой. Во-вторых, когда я их удаляю, то почему-то на каком-то файле процесс удаления зависает. У меня возникло такое впечатление, что это какие-то проблемы с кэшем. Ведь эти файлы только что были загружены из Internet и возможно еще не записаны из кэша на винчестер. Соответственно возникает второй вопрос: как принудительно сохранить буфер кэша на винчестер из программы на Аляске? Ниже фрагмент кода программы, который все это делает:

Re: How to read the contents of a folder on a web server via

Posted: Fri May 05, 2017 11:56 pm
by Eugene Lutsenko
Does anyone know why these downloads are not deleted. Like seemingly everything is simple and usually all works well, but not in this case

Code: Select all

      FOR j=1 TO LEN(aFileName)
          Name_SS = aFileName[j]
          Name_DD = Disk_dir+"\AID_DATA\Inp_data\"+aFileName[j]
          COPY FILE (Name_SS) TO (Name_DD)
      NEXT
      FOR j=1 TO LEN(aFileName)
          IF FILE(aFileName[j])
*            ERASE(aFileName[j])
             DELETE FILE (aFileName[j])
          ENDIF
      NEXT
Looks like a few files deleted, and then the program hangs

Re: How to read the contents of a folder on a web server via

Posted: Sat May 06, 2017 1:12 am
by hz_scotty
try filedelete() from the xbase++ Tools or
DC_FileDel('JUNK') from express++

Re: How to read the contents of a folder on a web server via

Posted: Sat May 06, 2017 7:53 am
by rdonnay
Give this a try:

Code: Select all

      FOR j=1 TO LEN(aFileName)
          Name_SS = DC_CurPath() + '\' + aFileName[j]
          Name_DD = Disk_dir+"\AID_DATA\Inp_data\"+aFileName[j]
          COPY FILE (Name_SS) TO (Name_DD)
          ERASE ( Name_SS )
      NEXT