This module implements an asynchronous FTP client. It allows you to connect to an FTP server and perform operations on it such as for example:
In order to begin any sort of transfer of files you must first connect to an FTP server. You can do so with the connect
procedure.
import asyncdispatch, asyncftpclient proc main() {.async.} = var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test") await ftp.connect() echo("Connected") waitFor(main())
A new main
async procedure must be declared to allow the use of the await
keyword. The connection will complete asynchronously and the client will be connected after the await ftp.connect()
call.
After a connection is made you can use the store
procedure to upload a new file to the FTP server. Make sure to check you are in the correct working directory before you do so with the pwd
procedure, you can also instead specify an absolute path.
import asyncdispatch, asyncftpclient proc main() {.async.} = var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test") await ftp.connect() let currentDir = await ftp.pwd() assert currentDir == "/home/user/" await ftp.store("file.txt", "file.txt") echo("File finished uploading") waitFor(main())
The progress of either a file upload or a file download can be checked by specifying a onProgressChanged
procedure to the store
or retrFile
procedures.
import asyncdispatch, asyncftpclient proc onProgressChanged(total, progress: BiggestInt, speed: float): Future[void] = echo("Uploaded ", progress, " of ", total, " bytes") echo("Current speed: ", speed, " kb/s") proc main() {.async.} = var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test") await ftp.connect() await ftp.store("file.txt", "/home/user/file.txt", onProgressChanged) echo("File finished uploading") waitFor(main())
AsyncFtpClientObj = FtpBaseObj[AsyncSocket]
AsyncFtpClient = ref AsyncFtpClientObj
ProgressChangedProc = proc (total, progress: BiggestInt; speed: float): Future[void] {...}{. closure, gcsafe.}
proc send(ftp: AsyncFtpClient; m: string): Future[TaintedString] {...}{. raises: [FutureError], tags: [RootEffect].}
Send a message to the server, and wait for a primary reply. \c\L
is added for you.
Note: The server may return multiple lines of coded replies.
proc connect(ftp: AsyncFtpClient): Future[void] {...}{.raises: [FutureError], tags: [RootEffect].}
ftp
. proc pwd(ftp: AsyncFtpClient): Future[TaintedString] {...}{.raises: [FutureError], tags: [RootEffect].}
proc cd(ftp: AsyncFtpClient; dir: string): Future[void] {...}{.raises: [FutureError], tags: [RootEffect].}
dir
. proc cdup(ftp: AsyncFtpClient): Future[void] {...}{.raises: [FutureError], tags: [RootEffect].}
proc listDirs(ftp: AsyncFtpClient; dir = ""): Future[seq[string]] {...}{. raises: [FutureError], tags: [RootEffect].}
dir
is "", the current directory is used. If async
is true, this function will return immediately and it will be your job to use asyncio's poll
to progress this operation. proc existsFile(ftp: AsyncFtpClient; file: string): Future[bool] {...}{. raises: [FutureError], tags: [RootEffect].}
file
exists. proc createDir(ftp: AsyncFtpClient; dir: string; recursive = false): Future[void] {...}{. raises: [FutureError], tags: [RootEffect].}
dir
. If recursive
is true, the topmost subdirectory of dir
will be created first, following the secondmost... etc. this allows you to give a full path as the dir
without worrying about subdirectories not existing. proc chmod(ftp: AsyncFtpClient; path: string; permissions: set[FilePermission]): Future[ void] {...}{.raises: [FutureError], tags: [RootEffect].}
path
to permissions
. proc list(ftp: AsyncFtpClient; dir = ""): Future[string] {...}{.raises: [FutureError], tags: [RootEffect].}
dir
. If dir
is ""
, uses the current working directory. proc retrText(ftp: AsyncFtpClient; file: string): Future[string] {...}{. raises: [FutureError], tags: [RootEffect].}
file
. File must be ASCII text. proc defaultOnProgressChanged(total, progress: BiggestInt; speed: float): Future[void] {...}{. nimcall, gcsafe, procvar, raises: [FutureError, Exception], tags: [RootEffect].}
onProgressChanged
handler. Does nothing. proc retrFile(ftp: AsyncFtpClient; file, dest: string; onProgressChanged: ProgressChangedProc = defaultOnProgressChanged): Future[ void] {...}{.raises: [FutureError], tags: [RootEffect, TimeEffect, WriteIOEffect].}
file
and saves it to dest
. The EvRetr
event is passed to the specified handleEvent
function when the download is finished. The event's filename
field will be equal to file
. proc store(ftp: AsyncFtpClient; file, dest: string; onProgressChanged: ProgressChangedProc = defaultOnProgressChanged): Future[ void] {...}{.raises: [FutureError], tags: [RootEffect, ReadIOEffect, TimeEffect].}
file
to dest
on the remote FTP server. Usage of this function asynchronously is recommended to view the progress of the download. The EvStore
event is passed to the specified handleEvent
function when the upload is finished, and the filename
field will be equal to file
. proc rename(ftp: AsyncFtpClient; nameFrom: string; nameTo: string): Future[void] {...}{. raises: [FutureError], tags: [RootEffect].}
name_from
to new name name_to
proc removeFile(ftp: AsyncFtpClient; filename: string): Future[void] {...}{. raises: [FutureError], tags: [RootEffect].}
filename
on the remote FTP server proc removeDir(ftp: AsyncFtpClient; dir: string): Future[void] {...}{. raises: [FutureError], tags: [RootEffect].}
dir
on the remote FTP server proc newAsyncFtpClient(address: string; port = Port(21); user, pass = ""): AsyncFtpClient {...}{. raises: [OSError, Exception], tags: [RootEffect].}
AsyncFtpClient
object.
© 2006–2018 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/asyncftpclient.html