asyncftpclient
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:
- The upload of new files.
- The removal of existing files.
- Download of files.
- Changing of files' permissions.
- Navigation through the FTP server's directories.
Connecting to an FTP server
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.
Uploading a new file
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()) Checking the progress of a file transfer
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.
Procs that take an onProgressChanged callback will call this every progressInterval milliseconds.
import asyncdispatch, asyncftpclient
proc onProgressChanged(total, progress: BiggestInt,
speed: float) {.async.} =
echo("Uploaded ", progress, " of ", total, " bytes")
echo("Current speed: ", speed, " kb/s")
proc main() {.async.} =
var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test", progressInterval = 500)
await ftp.connect()
await ftp.store("file.txt", "/home/user/file.txt", onProgressChanged)
echo("File finished uploading")
waitFor(main()) Imports
Types
AsyncFtpClient = ref object csock*: AsyncSocket dsock*: AsyncSocket user*, pass*: string address*: string port*: Port progressInterval: int jobInProgress*: bool job*: FtpJob dsockConnected*: bool
- Source Edit
FtpJobType = enum JRetrText, JRetr, JStore
- Source Edit
FtpEventType = enum EvTransferProgress, EvLines, EvRetr, EvStore
- Source Edit
FtpEvent = object filename*: string case typ*: FtpEventType of EvLines: lines*: string ## Lines that have been transferred. of EvRetr, EvStore: ## Retr/Store operation finished. nil of EvTransferProgress: bytesTotal*: BiggestInt ## Bytes total. bytesFinished*: BiggestInt ## Bytes transferred. speed*: BiggestInt ## Speed in bytes/s currentJob*: FtpJobType ## The current job being performed.- Event Source Edit
ReplyError = object of IOError
- Source Edit
ProgressChangedProc = proc (total, progress: BiggestInt; speed: float): Future[ void] {...}{.closure, gcsafe.}- Source Edit
Procs
proc send(ftp: AsyncFtpClient; m: string): Future[TaintedString] {...}{. raises: [Exception, ValueError], tags: [RootEffect].}-
Send a message to the server, and wait for a primary reply.
\c\Lis added for you.You need to make sure that the message
mdoesn't contain any newline characters. Failing to do so will raiseAssertionDefect.Note: The server may return multiple lines of coded replies.
Source Edit proc connect(ftp: AsyncFtpClient): owned(Future[void]) {...}{.raises: [Exception], tags: [RootEffect].}- Connect to the FTP server specified by
ftp. Source Edit proc pwd(ftp: AsyncFtpClient): Future[TaintedString] {...}{. raises: [Exception, ValueError], tags: [RootEffect].}- Returns the current working directory. Source Edit
proc cd(ftp: AsyncFtpClient; dir: string): owned(Future[void]) {...}{. raises: [Exception], tags: [RootEffect].}- Changes the current directory on the remote FTP server to
dir. Source Edit proc cdup(ftp: AsyncFtpClient): owned(Future[void]) {...}{.raises: [Exception], tags: [RootEffect].}- Changes the current directory to the parent of the current directory. Source Edit
proc listDirs(ftp: AsyncFtpClient; dir = ""): Future[seq[string]] {...}{. raises: [Exception, ValueError], tags: [RootEffect].}- Returns a list of filenames in the given directory. If
diris "", the current directory is used. Ifasyncis true, this function will return immediately and it will be your job to use asyncdispatch'spollto progress this operation. Source Edit proc fileExists(ftp: AsyncFtpClient; file: string): Future[bool] {...}{. raises: [Exception, ValueError], tags: [RootEffect].}- Determines whether
fileexists. Source Edit proc createDir(ftp: AsyncFtpClient; dir: string; recursive = false): owned( Future[void]) {...}{.raises: [Exception], tags: [RootEffect].}- Creates a directory
dir. Ifrecursiveis true, the topmost subdirectory ofdirwill be created first, following the secondmost... etc. this allows you to give a full path as thedirwithout worrying about subdirectories not existing. Source Edit proc chmod(ftp: AsyncFtpClient; path: string; permissions: set[FilePermission]): owned( Future[void]) {...}{.raises: [Exception], tags: [RootEffect].}- Changes permission of
pathtopermissions. Source Edit proc list(ftp: AsyncFtpClient; dir = ""): Future[string] {...}{. raises: [Exception, ValueError], tags: [RootEffect].}- Lists all files in
dir. Ifdiris"", uses the current working directory. Source Edit proc retrText(ftp: AsyncFtpClient; file: string): Future[string] {...}{. raises: [Exception, ValueError], tags: [RootEffect].}- Retrieves
file. File must be ASCII text. Source Edit proc defaultOnProgressChanged(total, progress: BiggestInt; speed: float): Future[ void] {...}{.nimcall, gcsafe, raises: [Exception], tags: [RootEffect].}- Default FTP
onProgressChangedhandler. Does nothing. Source Edit proc retrFile(ftp: AsyncFtpClient; file, dest: string; onProgressChanged: ProgressChangedProc = defaultOnProgressChanged): owned( Future[void]) {...}{.raises: [Exception], tags: [RootEffect, TimeEffect, WriteIOEffect].}- Downloads
fileand saves it todest. TheEvRetrevent is passed to the specifiedhandleEventfunction when the download is finished. The event'sfilenamefield will be equal tofile. Source Edit proc store(ftp: AsyncFtpClient; file, dest: string; onProgressChanged: ProgressChangedProc = defaultOnProgressChanged): owned( Future[void]) {...}{.raises: [Exception], tags: [RootEffect, ReadIOEffect, TimeEffect].}- Uploads
filetodeston the remote FTP server. Usage of this function asynchronously is recommended to view the progress of the download. TheEvStoreevent is passed to the specifiedhandleEventfunction when the upload is finished, and thefilenamefield will be equal tofile. Source Edit proc rename(ftp: AsyncFtpClient; nameFrom: string; nameTo: string): owned( Future[void]) {...}{.raises: [Exception], tags: [RootEffect].}- Rename a file or directory on the remote FTP Server from current name
name_fromto new namename_toSource Edit proc removeFile(ftp: AsyncFtpClient; filename: string): owned(Future[void]) {...}{. raises: [Exception], tags: [RootEffect].}- Delete a file
filenameon the remote FTP server Source Edit proc removeDir(ftp: AsyncFtpClient; dir: string): owned(Future[void]) {...}{. raises: [Exception], tags: [RootEffect].}- Delete a directory
diron the remote FTP server Source Edit proc newAsyncFtpClient(address: string; port = Port(21); user, pass = ""; progressInterval: int = 1000): AsyncFtpClient {...}{. raises: [OSError, Exception], tags: [RootEffect].}- Creates a new
AsyncFtpClientobject. Source Edit
© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/asyncftpclient.html