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

This forum is for eXpress++ general support.
Message
Author
User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

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

#1 Post 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:
Attachments
err.jpg
err.jpg (89.72 KiB) Viewed 15812 times
Roger.jpg
Roger.jpg (162.55 KiB) Viewed 15812 times

User avatar
rdonnay
Site Admin
Posts: 4745
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

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

#2 Post 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.
The eXpress train is coming - and it has more cars.

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

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

#3 Post 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
Attachments
dir.jpg
dir.jpg (66.16 KiB) Viewed 15802 times

User avatar
rdonnay
Site Admin
Posts: 4745
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

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

#4 Post 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 
The eXpress train is coming - and it has more cars.

Cliff Wiernik
Posts: 605
Joined: Thu Jan 28, 2010 9:11 pm
Location: Steven Point, Wisconsin USA
Contact:

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

#5 Post 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.

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

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

#6 Post 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!!!
Attachments
Безымянный.jpg
Безымянный.jpg (206.73 KiB) Viewed 15786 times

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

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

#7 Post 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 и возможно еще не записаны из кэша на винчестер. Соответственно возникает второй вопрос: как принудительно сохранить буфер кэша на винчестер из программы на Аляске? Ниже фрагмент кода программы, который все это делает:
Last edited by Eugene Lutsenko on Fri May 05, 2017 11:56 pm, edited 1 time in total.

User avatar
Eugene Lutsenko
Posts: 1649
Joined: Sat Feb 04, 2012 2:23 am
Location: Russia, Southern federal district, city of Krasnodar
Contact:

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

#8 Post 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
Last edited by Eugene Lutsenko on Sat May 06, 2017 1:13 am, edited 1 time in total.

User avatar
hz_scotty
Posts: 107
Joined: Thu Jan 28, 2010 8:20 am
Location: Wr.Neustadt / Österreich

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

#9 Post by hz_scotty »

try filedelete() from the xbase++ Tools or
DC_FileDel('JUNK') from express++
best regards
Hans

User avatar
rdonnay
Site Admin
Posts: 4745
Joined: Wed Jan 27, 2010 6:58 pm
Location: Boise, Idaho USA
Contact:

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

#10 Post 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
The eXpress train is coming - and it has more cars.

Post Reply