Reed

Been Lurking Now Stuck on FTP

11 posts in this topic

#1 ·  Posted (edited)

Hello,

I'm new here but I've been an active lurker on this forum to see how far I could get without posting and here I am.

I am creating an FTP program that works in conjunction with windows task scheduler and will transfer files automatically at certain times of day.

I was using the function _FTP_FileGet and was wondering if this function works on folders.  Can I copy an entire folder and its contents to a place on my hard drive?

Here's my code: (It's a function and the FTP information is taken out for obvious reasons)

I have several message boxes in there for testing purposes so I can see what is happening as I run the code.

#include <FTPEx.au3>
#include <Array.au3>
#include <Date.au3>

Func CheckUpload($sServer, $sUsername, $sPass, $FileName)

Local $hOpen = _FTP_Open('MyFTP Control', $INTERNET_OPEN_TYPE_PRECONFIG)
Local $hConn = _FTP_Connect($hOpen, $sServer, $sUsername, $sPass)

Local $aFile = _FTP_ListToArray($hConn, 2)
; Converts the directory list of files from an array to a string for searching
$aFileString = _ArrayToString($aFile)

; Searches for $FileName 0 if not found, otherwise
; It returns a number that's the position of the text.
$aFileCheck = StringInStr($aFileString, $FileName)

if($aFileCheck <> 0) Then Sleep(300000)
if($aFileCheck <> 0) Then Run(@AutoItExe)
if($aFileCheck <> 0) Then ProcessClose(@AutoItPID)

Local $iFtpc = _FTP_Close($hConn)
Local $iFtpo = _FTP_Close($hOpen)
EndFunc

Func _Date($mdays)
  ; -- Get Date information for file typing (-6 days) --
     Local $PastDate = _DateAdd('d', -$mdays, _NowCalcDate())
  ; -- Format Date correctly for directory navigation --
     $PastDate = _DateTimeFormat($PastDate, 2)
     If(StringLeft("$PastDate",2) < 10) Then $PastDate = "0"&$PastDate
     $PastDate = StringReplace($PastDate,"/","-")
  ; -- Format the year for folder selection --
     $PastDate = StringReplace($PastDate,"2015","15")
      Return $PastDate
EndFunc

MsgBox(0,"Date Check",_Date(6))

Func CopyPPC($sServer, $sUsername, $sPass, $Days)

Local $hOpen = _FTP_Open('MyFTP Control', $INTERNET_OPEN_TYPE_PRECONFIG)
Local $hConn = _FTP_Connect($hOpen, $sServer, $sUsername, $sPass)

_FTP_DirSetCurrent($hConn, "/t9/log1/"&_Date(6))


Local $aFile = _FTP_ListToArray($hConn)
; Converts the directory list of files from an array to a string for searching
/display
$aFileString = _ArrayToString($aFile)

_FTP_FileGet($hConn,@DesktopDir,$aFile[1])


MsgBox(0,"$aFile[1]",$aFile[1])

MsgBox(0,"Huge File List", $aFileString & @LF & @LF & _FTP_DirGetCurrent($hConn))

Local $iFtpc = _FTP_Close($hConn)
Local $iFtpo = _FTP_Close($hOpen)
EndFunc

I put the part I'm working on in Red to make it easier for everyone to see.

I'm just wondering if there's a way to copy a folder using this function or am I doing something wrong?

 

Also, I am relatively new to AutoIt but I've been using it for about 2 months 5 days a week for about 2-7 hours a day and I REALLY LOVE AUTOIT!

 

Thank you for any help I receive even if it's to link me somewhere else I don't mind!

Edited by Reed

Share this post


Link to post
Share on other sites



Reed,

Welcome to the AutoIt forum.

But please pay attention to where you post - the "Dev Chat" section where you started this thread is not for general support questions.  I have moved it for you, but would ask you to be more careful in future.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Reed,

Welcome to the AutoIt forum.

But please pay attention to where you post - the "Dev Chat" section where you started this thread is not for general support questions.  I have moved it for you, but would ask you to be more careful in future.

M23

​Sorry about that!  I wasn't entirely 100% sure of what section to post this in and it looks like I goofed.  It won't happen again!

Share this post


Link to post
Share on other sites

Reed,

No problems - you are certainly neither the first nor the last to do it!

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

You'll need to make a For...To...Step...Next loop, and loop through all the files in the Dir. Which, you can specify to a certain folder of your choosing that they all download into. Essentially pulling the whole Dir into the local Dir. 

I do not know of a way of using FTP functions to pull down a folder, only as I described above.

Edited by MikahS
syntax

Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
Share on other sites

I just made a ftp program and ran into the same issue.

There is no native _FTP_DirGet - I did find a user created UDF for it but had no luck with it so what I did was FileListToArray (The FTP Version) and specified files only and got them all in a loop.

Then I used FileListToArray again specifing only directories, and then fed that information to a loop that changed my current FTP home directory so that I could start the first process again of listing all the files and downloading them.

I'll post my code incase it helps.  Regards.

#Include <FTPEx.au3>
#Include <Array.au3>
#Include <File.au3>

$vFTPSes = _FTP_Open("PSFTP")
$vFTPSes2 = _FTP_Connect($vFTPSes, "snip", "snip", "snip")
If @Error <> 0 Then
    MsgBox(0, "Black Magic Automation", "Could Not Connect to Download Server, Please try again later")
    Exit
EndIf

_FTP_DirSetCurrent($vFTPSes2, "/Tiburon FTP Update/Maps/")

Global $aFile2 = _FTP_ListToArray($vFTPSes2, 1)
Global $sLocalSave = "C:\Tiburon\MapFTP\Maps\"
Global $sMap1 = "C:\Tiburon\911Mapping\Mobile\Maps\"
Global $sMap2 = "C:\Tiburon\911Mapping\Maverick\Maps\"
Global $aFixFile

DirRemove($sLocalSave, 1)
DirCreate($sLocalSave)
SplashTextOn("Black Magic Automation", "Downloading Map Updates...", 200, 40, 0, 0, 1, "", 8)
Download($sLocalSave)

For $i2 = 1 To UBound($aFile2) - 1
    _FTP_DirSetCurrent($vFTPSes2, "/Tiburon FTP Update/Maps/" & $aFile2[$i2])
    $sLocalSaveNew = $sLocalSave & $aFile2[$i2] & "\"
    DirCreate($sLocalSaveNew)
    Download($sLocalSaveNew)
Next

Func Download($sLocalSave)
$aFile = _FTP_ListToArray($vFTPSes2, 2)

For $i = 1 To UBound($aFile) - 1
    _FTP_FileGet($vFTPSes2, $aFile[$i], $sLocalSave & $aFile[$i])
    ;_FTP_ProgressDownload($vFTPSes2, $sLocalSave & $aFile[$i], $aFile[$i])
    If @Error <> 0 Then
    MsgBox(0, "Black Magic Automation", "FTP Download Failed, Please try again later")
    _FTP_Close($vFTPSes2)
    Exit
EndIf
Next
EndFunc

_FileReadToArray($sLocalSave & "\Map Info.txt", $aFixFile, 0)
;_ArrayDisplay($aFixFile)
_FileWriteFromARray($sLocalSave & "\Map Info.txt", $aFixFile)

$sDLSize = FileReadLine($sLocalSave & "\Map Info.txt", 1)
$sDLCount = FileReadLine($sLocalSave & "\Map Info.txt", 2)
$aLocalDL = DirGetSize($sLocalSave, 1)


_FTP_Close($vFTPSes2)
SplashOff()

If $sDLSize = $aLocalDL[0] AND $sDLCount = $aLocalDL[1] Then
    MsgBox(0, "Black Magic Automation", "Tiburon Map Download Complete." & @CRLF & "Please Close Tiburon and Press -OK- To Install Updates.")
    SplashTextOn("Black Magic Automation", "Installing Map Updates...", 200, 40, 0, 0, 1, "", 8)
    If ProcessExists("TiburonInc.MobileCOM.Main.MobileCOM.exe") Then ProcessClose("TiburonInc.MobileCOM.Main.MobileCOM.exe")
    DirCopy($sLocalSave, $sMap1, 1)
    DirCopy($sLocalSave, $sMap2, 1)
    SplashOff()
    MsgBox(0, "Black Magic Automation", "Tiburon Map Files Have been Updated Sucsessfully!" & @CRLF & @CRLF & "You May Now Open Tiburon and Continue Work.")
Else
    MsgBox(0, "Black Magic Automation", "Tiburon Map Updates Did Not Download Fully, Please Try Again Later")
    Exit
EndIf

 

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

You'll need to make a For...Next loop, and loop through all the files in the Dir. Which, you can specify to a certain folder of your choosing that they all download into. Essentially pulling the whole Dir into the local Dir. 

I do not know of a way of using FTP functions to pull down a folder, only as I described above.

​Okay, so there's no way to copy a folder using a built in windows function or anything?  Because if I do as you suggest, we then run into the problem of having subsequent folders inside of that folder.  Which will create a recursion nightmare for me...  I'd rather not if there's a simpler way to do it.

Some additional information:
When I access the server via the command prompt by typing FTP <SERVER IP>, From that shell I can use several commands, here's a list of them.

commands.thumb.jpg.92787fb69b0e18a366ca0

 

Will the _FTP_Command() function work for these functions?  I tried it before but I couldn't figure out how to pass the commands to the server correctly...

 

Edited by Reed

Share this post


Link to post
Share on other sites

I just made a ftp program and ran into the same issue.

There is no native _FTP_DirGet - I did find a user created UDF for it but had no luck with it so what I did was FileListToArray (The FTP Version) and specified files only and got them all in a loop.

Then I used FileListToArray again specifing only directories, and then fed that information to a loop that changed my current FTP home directory so that I could start the first process again of listing all the files and downloading them.

I'll post my code incase it helps.  Regards.

#Include <FTPEx.au3>
#Include <Array.au3>
#Include <File.au3>

$vFTPSes = _FTP_Open("PSFTP")
$vFTPSes2 = _FTP_Connect($vFTPSes, "snip", "snip", "snip")
If @Error <> 0 Then
    MsgBox(0, "Black Magic Automation", "Could Not Connect to Download Server, Please try again later")
    Exit
EndIf

_FTP_DirSetCurrent($vFTPSes2, "/Tiburon FTP Update/Maps/")

Global $aFile2 = _FTP_ListToArray($vFTPSes2, 1)
Global $sLocalSave = "C:\Tiburon\MapFTP\Maps\"
Global $sMap1 = "C:\Tiburon\911Mapping\Mobile\Maps\"
Global $sMap2 = "C:\Tiburon\911Mapping\Maverick\Maps\"
Global $aFixFile

DirRemove($sLocalSave, 1)
DirCreate($sLocalSave)
SplashTextOn("Black Magic Automation", "Downloading Map Updates...", 200, 40, 0, 0, 1, "", 8)
Download($sLocalSave)

For $i2 = 1 To UBound($aFile2) - 1
    _FTP_DirSetCurrent($vFTPSes2, "/Tiburon FTP Update/Maps/" & $aFile2[$i2])
    $sLocalSaveNew = $sLocalSave & $aFile2[$i2] & "\"
    DirCreate($sLocalSaveNew)
    Download($sLocalSaveNew)
Next

Func Download($sLocalSave)
$aFile = _FTP_ListToArray($vFTPSes2, 2)

For $i = 1 To UBound($aFile) - 1
    _FTP_FileGet($vFTPSes2, $aFile[$i], $sLocalSave & $aFile[$i])
    ;_FTP_ProgressDownload($vFTPSes2, $sLocalSave & $aFile[$i], $aFile[$i])
    If @Error <> 0 Then
    MsgBox(0, "Black Magic Automation", "FTP Download Failed, Please try again later")
    _FTP_Close($vFTPSes2)
    Exit
EndIf
Next
EndFunc

_FileReadToArray($sLocalSave & "\Map Info.txt", $aFixFile, 0)
;_ArrayDisplay($aFixFile)
_FileWriteFromARray($sLocalSave & "\Map Info.txt", $aFixFile)

$sDLSize = FileReadLine($sLocalSave & "\Map Info.txt", 1)
$sDLCount = FileReadLine($sLocalSave & "\Map Info.txt", 2)
$aLocalDL = DirGetSize($sLocalSave, 1)


_FTP_Close($vFTPSes2)
SplashOff()

If $sDLSize = $aLocalDL[0] AND $sDLCount = $aLocalDL[1] Then
    MsgBox(0, "Black Magic Automation", "Tiburon Map Download Complete." & @CRLF & "Please Close Tiburon and Press -OK- To Install Updates.")
    SplashTextOn("Black Magic Automation", "Installing Map Updates...", 200, 40, 0, 0, 1, "", 8)
    If ProcessExists("TiburonInc.MobileCOM.Main.MobileCOM.exe") Then ProcessClose("TiburonInc.MobileCOM.Main.MobileCOM.exe")
    DirCopy($sLocalSave, $sMap1, 1)
    DirCopy($sLocalSave, $sMap2, 1)
    SplashOff()
    MsgBox(0, "Black Magic Automation", "Tiburon Map Files Have been Updated Sucsessfully!" & @CRLF & @CRLF & "You May Now Open Tiburon and Continue Work.")
Else
    MsgBox(0, "Black Magic Automation", "Tiburon Map Updates Did Not Download Fully, Please Try Again Later")
    Exit
EndIf
 

​Looking over your code right now.  It's really unique, you use the code completely differently than I do.  It may take me some time to figure out exactly how you are doing this.  If there are multiple sub folders or folders within folders, do you have a function that recursively creates more arrays for each subsequent folder?

I guess I'm just a bit confused about the code since there aren't any comments explaining what each section does. (I try to do this as I code so that it's easy to come back to my code and understand it and for other people who read it)  Also, I don't know everything that you modified (removed).  I can assume it was the server information...  Was there anything else?

Share this post


Link to post
Share on other sites

No lucky for me my directories are only a single level deep, I guess I would have to check for further directories as part of my function and pass that out somehow, since I did not need to do that I did not explode my brain trying to figure it out.

 

Also this is only my "download" code I have another that is my "check for download" and it pulls just the Map Info.txt file and compares it against the local download to determin if it needs to launch this script.  This way it runs when needed but not when it is not.

I tried to get .exe to run with Task Scheduler before without much luck :/

Share this post


Link to post
Share on other sites

#10 ·  Posted

 ​Today I made my first attempt at coding this and I am getting stuck. Maybe my brain is just too dumb to comprehend this or I am going mad with the details of using this but here's what I have so far:

#include <FTPEx.au3>
#include <Array.au3>
#include <Date.au3>


; This function check for a file on the upload server. File is defined by $FileName
Func CheckUpload($sServer, $sUsername, $sPass, $FileName)

Local $hOpen = _FTP_Open('MyFTP Control', $INTERNET_OPEN_TYPE_PRECONFIG)
Local $hConn = _FTP_Connect($hOpen, $sServer, $sUsername, $sPass)

Local $aFile = _FTP_ListToArray($hConn, 2)
; Converts the directory list of files from an array to a string for searching
$aFileString = _ArrayToString($aFile)

; Searches for $FileName 0 if not found, otherwise
; It returns a number that's the position of the text.
$aFileCheck = StringInStr($aFileString, $FileName)

if($aFileCheck <> 0) Then Sleep(300000)
if($aFileCheck <> 0) Then Run(@AutoItExe)
if($aFileCheck <> 0) Then ProcessClose(@AutoItPID)

Local $iFtpc = _FTP_Close($hConn)
Local $iFtpo = _FTP_Close($hOpen)
EndFunc

; This function changes the format of the date in order to navigate the server
Func _Date($mdays)
  ; -- Get Date information for file typing (-6 days) --
     Local $PastDate = _DateAdd('d', -$mdays, _NowCalcDate())
  ; -- Format Date correctly for directory navigation --
     $PastDate = _DateTimeFormat($PastDate, 2)
     If(StringLeft("$PastDate",2) < 10) Then $PastDate = "0"&$PastDate
     $PastDate = StringReplace($PastDate,"/","-")
  ; -- Format the year for folder selection --
     $PastDate = StringReplace($PastDate,"2015","15")
      Return $PastDate
EndFunc

; This function copies files that were found on the server in the current directory.
Func FTFiles($f,$serv)
   For $i = 1 To $i > UBOUND($f)-1 Step +1
      FTP_FileGet($hConn,"@DesktopDir"&$serv,$f[$i])
   Next
EndFunc

; This function recreates folders from the current directory of the server
Func CopyFolds($f,$serv)
   For $i=1 To UBOUND($f)-1 Step +1
      DirCreate("@DesktopDir"&$serv&"\"&$f[$i]&"\")
   Next
EndFunc

Func CopyPPC($sServer, $sUsername, $sPass, $Days, $PServer)

$Day = $Days
Local $hOpen = _FTP_Open('MyFTP Control', $INTERNET_OPEN_TYPE_PRECONFIG)
Local $hConn = _FTP_Connect($hOpen, $sServer, $sUsername, $sPass)


; Sets the current directory to the appropriate gunther server.
_FTP_DirSetCurrent($hConn, "/t"&$PServer&"/log1/"&_Date($Day))



   ; Finding ONLY Folders in the current directory in order to recreate them locally.
   $aFolders1 = _FTP_ListToArray($hConn,1)
   ; Recreates folders locally
   If(UBOUND($aFolders1) > 1) Then CopyFolds($aFolders1,$PServer)

For $i = 1 to UBOUND($aFolders1)-1 Step +1
   ; Finding ONLY files in order to copy them.
   $aFiles = _FTP_ListToArray($hConn, 2)
   ; Copying files from server
   If(UBOUND($aFiles) > 1) Then FTFiles($aFiles,$PServer)

   _FTP_DirSetCurrent($hConn, "/t"&$PServer&"/log1/"&_Date($Day)&"/"&$aFolders1[$i]&"/")

   ; Finding ONLY Folders in the current directory in order to recreate them locally.
   $aFolders2 = _FTP_ListToArray($hConn,1)

   If(UBOUND($aFolders2) < 1) Then ExitLoop

   CopyFolds($aFolders2,$PServer)
Next


; Converts the directory list of files from an array to a string for searching
$aFileString = _ArrayToString($aFiles)


MsgBox(0,"Huge File List", $aFileString & @LF & @LF & _FTP_DirGetCurrent($hConn))

Local $iFtpc = _FTP_Close($hConn)
Local $iFtpo = _FTP_Close($hOpen)
EndFunc

I am stuck at the part where it recursively navigates through the sub folders without losing track of each iteration of a folder...

 

You'll need to make a For...To...Step...Next loop, and loop through all the files in the Dir. Which, you can specify to a certain folder of your choosing that they all download into. Essentially pulling the whole Dir into the local Dir. 

I do not know of a way of using FTP functions to pull down a folder, only as I described above.

You seem to have a better idea of what to do.  Can you provide me with more context of what you're describing?  Like with Specific syntax... EX: FTP_DirSetCurrent, then Copy files over, then store folders in an array, then create folders locally, then copy files, then copy folders (Repeat last 2)

I can get the last 2 repeating but I cannot even figure out logically how to do it recursively while maintaining the information about the previous folder sets.  The only thing I can think of would be to recursively create arrays and store them and know how to refer to them, but I have no idea how to do that with any programming language and that might be a fault of my own!

Please provide more information. :o

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

I'll see if I can whip up an example.

Also: if you want to have a look at how Recursion works, Have a look at the Recursion wiki page.

Edited by MikahS
link and text

Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now