Module ftpclient

This module partially implements an FTP client as specified by RFC 959.

This module provides both a synchronous and asynchronous implementation. The asynchronous implementation requires you to use the AsyncFTPClient function. You are then required to register the PAsyncFTPClient with a asyncio dispatcher using the register function. Take a look at the asyncio module documentation for more information.

Note: The asynchronous implementation is only asynchronous for long file transfers, calls to functions which use the command socket will block.

Here is some example usage of this module:

var ftp = FTPClient("example.org", user = "user", pass = "pass")
ftp.connect()
ftp.retrFile("file.ext", "file.ext")

Warning: The API of this module is unstable, and therefore is subject to change.

Types

TFTPClient = object of TObject
  case isAsync: bool
  of false: 
      csock: TSocket
      dsock: TSocket

  else: 
      dummyA, dummyB: pointer
      asyncCSock: PAsyncSocket
      asyncDSock: PAsyncSocket
      handleEvent*: proc (ftp: PAsyncFTPClient; ev: TFTPEvent) {.closure.}
      disp: PDispatcher
      asyncDSockID: PDelegate

  user, pass: string
  address: string
  port: TPort
  jobInProgress: bool
  job: ref TFTPJob
  dsockConnected: bool
PFTPClient = ref TFTPClient
FTPJobType = enum 
  JRetrText, JRetr, JStore
PAsyncFTPClient = ref TAsyncFTPClient
Async alternative to TFTPClient.
TAsyncFTPClient = object of TFTPClient
FTPEventType = enum 
  EvTransferProgress, EvLines, EvRetr, EvStore
TFTPEvent = 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
EInvalidReply = object of ESynch
EFTP = object of ESynch

Procs

proc ftpClient(address: string; port = TPort(21); user, pass = ""): PFTPClient {.
    raises: [], tags: [].}
Create a PFTPClient object.
proc send(ftp: PFTPClient; m: string): TaintedString {.
    raises: [EOS, EInvalidValue, ETimeout], tags: [FWriteIO, FReadIO, FTime].}
Send a message to the server, and wait for a primary reply. \c\L is added for you.
proc connect(ftp: PFTPClient) {.raises: [EOS, EInvalidReply, EInvalidValue, 
    ETimeout], tags: [FReadIO, FTime, FWriteIO].}
Connect to the FTP server specified by ftp.
proc pwd(ftp: PFTPClient): string {.raises: [EOS, EInvalidValue, ETimeout, 
    EInvalidReply], tags: [FWriteIO, FReadIO, FTime].}
Returns the current working directory.
proc cd(ftp: PFTPClient; dir: string) {.raises: [EInvalidReply, EInvalidValue, 
    EOS, ETimeout], tags: [FWriteIO, FReadIO, FTime].}
Changes the current directory on the remote FTP server to dir.
proc cdup(ftp: PFTPClient) {.raises: [EInvalidReply, EInvalidValue, EOS, 
                                      ETimeout], 
                             tags: [FWriteIO, FReadIO, FTime].}
Changes the current directory to the parent of the current directory.
proc listDirs(ftp: PFTPClient; dir: string = ""; async = false): seq[string] {.raises: [
    EFTP, EOS, ETimeout, EInvalidReply, EInvalidValue, EOverflow, E_Base], 
    tags: [FReadIO, FTime, FWriteIO, TEffect].}
Returns a list of filenames in the given directory. If 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 fileExists(ftp: PFTPClient; file: string): bool {.deprecated, raises: [
    EFTP, EOS, ETimeout, EInvalidReply, EInvalidValue, EOverflow, E_Base], 
    tags: [FReadIO, FTime, FWriteIO, TEffect].}

Deprecated since version 0.9.0: Please use existsFile.

Determines whether file exists.

Warning: This function may block. Especially on directories with many files, because a full list of file names must be retrieved.

proc existsFile(ftp: PFTPClient; file: string): bool {.raises: [EFTP, EOS, 
    ETimeout, EInvalidReply, EInvalidValue, EOverflow, E_Base], 
    tags: [FReadIO, FTime, FWriteIO, TEffect].}

Determines whether file exists.

Warning: This function may block. Especially on directories with many files, because a full list of file names must be retrieved.

proc createDir(ftp: PFTPClient; dir: string; recursive: bool = false) {.
    raises: [EInvalidReply, EInvalidValue, EOS, ETimeout], 
    tags: [FWriteIO, FReadIO, FTime].}
Creates a directory 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: PFTPClient; path: string; permissions: set[TFilePermission]) {.
    raises: [EInvalidReply, EInvalidValue, EOS, ETimeout], 
    tags: [FWriteIO, FReadIO, FTime].}
Changes permission of path to permissions.
proc list(ftp: PFTPClient; dir: string = ""; async = false): string {.raises: [
    EFTP, EOS, ETimeout, EInvalidReply, EInvalidValue, EOverflow, E_Base], 
    tags: [FReadIO, FTime, FWriteIO, TEffect].}
Lists all files in dir. If dir is "", uses the current working directory. If async is true, this function will return immediately and it will be your job to call asyncio's poll to progress this operation.
proc retrText(ftp: PFTPClient; file: string; async = false): string {.raises: [
    EFTP, EOS, ETimeout, EInvalidReply, EInvalidValue, EOverflow, E_Base], 
    tags: [FReadIO, FTime, FWriteIO, TEffect].}
Retrieves file. File must be ASCII text. If async is true, this function will return immediately and it will be your job to call asyncio's poll to progress this operation.
proc retrFile(ftp: PFTPClient; file, dest: string; async = false) {.raises: [
    EFTP, EOS, ETimeout, EIO, EInvalidReply, EInvalidValue, E_Base, EOverflow, 
    EInvalidReply, EInvalidReply], tags: [FReadIO, FTime, FWriteIO, TEffect].}
Downloads file and saves it to dest. Usage of this function asynchronously is recommended to view the progress of the download. The EvRetr event is passed to the specified handleEvent function when the download is finished, and the filename field will be equal to file.
proc store(ftp: PFTPClient; file, dest: string; async = false) {.raises: [EFTP, 
    EOS, EInvalidReply, EInvalidValue, ETimeout, E_Base, EIO, EOverflow], 
    tags: [FWriteIO, FReadIO, FTime, TEffect].}
Uploads 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 close(ftp: PFTPClient) {.raises: [EInvalidReply, EInvalidValue, EOS, 
                                       ETimeout], 
                              tags: [FWriteIO, FReadIO, FTime].}
Terminates the connection to the server.
proc asyncFTPClient(address: string; port = TPort(21); user, pass = ""; 
    handleEvent: proc (ftp: PAsyncFTPClient; ev: TFTPEvent) {.closure.} = (proc (
    ftp: PAsyncFTPClient; ev: TFTPEvent) = 
  discard )): PAsyncFTPClient {.raises: [EOS], tags: [].}

Create a PAsyncFTPClient object.

Use this if you want to use asyncio's dispatcher.

proc register(d: PDispatcher; ftp: PAsyncFTPClient): PDelegate {.discardable, 
    raises: [], tags: [].}
Registers ftp with dispatcher d.
Generated: 2014-03-11 21:26:52 UTC