diff options
author | Dominik Picheta <dominikpicheta@googlemail.com> | 2012-09-22 16:39:51 +0100 |
---|---|---|
committer | Dominik Picheta <dominikpicheta@googlemail.com> | 2012-09-22 16:39:51 +0100 |
commit | 6c6f9e66744384f29c3aabcb1b195f1f0bc5fa2c (patch) | |
tree | 0987cd15ef7881c7ad24a76dbeda74ab51f91e92 /lib | |
parent | 3ef146b0eacb8781dd0e352925001de342d6cc9d (diff) | |
download | Nim-6c6f9e66744384f29c3aabcb1b195f1f0bc5fa2c.tar.gz |
Ftpclient now fully works both synchronously and asynchronously.
Fixed some deprecation doc messages. And some issues with asyncio.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/asyncio.nim | 14 | ||||
-rw-r--r-- | lib/pure/ftpclient.nim | 336 | ||||
-rwxr-xr-x | lib/pure/sockets.nim | 4 |
3 files changed, 190 insertions, 164 deletions
diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 2ed4e2783..0de1da1c3 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -215,8 +215,12 @@ proc asyncSockHandleWrite(h: PObject) = if PAsyncSocket(h).info == SockConnecting: PAsyncSocket(h).handleConnect(PAsyncSocket(h)) - # Stop receiving write events - PAsyncSocket(h).deleg.mode = fmRead + PAsyncSocket(h).info = SockConnected + # Stop receiving write events if there is no handleWrite event. + if PAsyncSocket(h).handleWrite == nil: + PAsyncSocket(h).deleg.mode = fmRead + else: + PAsyncSocket(h).deleg.mode = fmReadWrite else: if PAsyncSocket(h).handleWrite != nil: PAsyncSocket(h).handleWrite(PAsyncSocket(h)) @@ -345,7 +349,7 @@ proc acceptAddr*(server: PAsyncSocket): tuple[sock: PAsyncSocket, address: string] {.deprecated.} = ## Equivalent to ``sockets.acceptAddr``. ## - ## **Warning**: This is deprecated in favour of the above. + ## **Deprecated since version 0.9.0:** Please use the function above. var client = newAsyncSocket() var address: string = "" acceptAddr(server, client, address) @@ -354,7 +358,7 @@ proc acceptAddr*(server: PAsyncSocket): tuple[sock: PAsyncSocket, proc accept*(server: PAsyncSocket): PAsyncSocket {.deprecated.} = ## Equivalent to ``sockets.accept``. ## - ## **Warning**: This is deprecated. + ## **Deprecated since version 0.9.0:** Please use the function above. new(result) var address = "" server.acceptAddr(result, address) @@ -510,6 +514,7 @@ proc poll*(d: PDispatcher, timeout: int = 500): bool = # File/socket has been closed. Remove it from dispatcher. d.delegates[dc] = d.delegates[len-1] dec len + d.delegates.setLen(len) var hasDataBufferedCount = 0 @@ -527,6 +532,7 @@ proc poll*(d: PDispatcher, timeout: int = 500): bool = for i in 0..len(d.delegates)-1: if i > len(d.delegates)-1: break # One delegate might've been removed. let deleg = d.delegates[i] + if not deleg.open: continue # This delegate might've been closed. if (deleg.mode != fmWrite or deleg.mode != fmAppend) and deleg notin readDg: deleg.handleRead(deleg.deleVal) diff --git a/lib/pure/ftpclient.nim b/lib/pure/ftpclient.nim index 46e17311c..0922f3344 100644 --- a/lib/pure/ftpclient.nim +++ b/lib/pure/ftpclient.nim @@ -29,14 +29,17 @@ import sockets, strutils, parseutils, times, os, asyncio type TFTPClient* = object of TObject - csock: TSocket # Command connection socket case isAsync: bool of false: + csock: TSocket # Command connection socket dsock: TSocket # Data connection socket else: dummyA, dummyB: pointer # workaround a Nimrod API issue - asyncCSock: PAsyncSocket # csock belongs to this. + asyncCSock: PAsyncSocket asyncDSock: PAsyncSocket + handleEvent*: proc (ftp: PAsyncFTPClient, ev: TFTPEvent) {.closure.} + disp: PDispatcher + asyncDSockID: PDelegate user, pass: string address: string port: TPort @@ -46,11 +49,13 @@ type dsockConnected: bool - FTPJobType = enum + PFTPClient* = ref TFTPClient + + FTPJobType* = enum JRetrText, JRetr, JStore TFTPJob = object - prc: proc (ftp: var TFTPClient, async: bool): bool {.nimcall.} + prc: proc (ftp: PFTPClient, async: bool): bool {.nimcall.} case typ*: FTPJobType of JRetrText: lines: string @@ -66,9 +71,6 @@ type PAsyncFTPClient* = ref TAsyncFTPClient ## Async alternative to TFTPClient. TAsyncFTPClient* = object of TFTPClient - handleEvent*: proc (ftp: var TAsyncFTPClient, ev: TFTPEvent) {.closure.} - disp: PDispatcher - asyncCSockID: PDelegate FTPEventType* = enum EvTransferProgress, EvLines, EvRetr, EvStore @@ -83,6 +85,7 @@ type bytesTotal*: biggestInt ## Bytes total. bytesFinished*: biggestInt ## Bytes transferred. speed*: biggestInt ## Speed in bytes/s + currentJob*: FTPJobType ## The current job being performed. EInvalidReply* = object of ESynch EFTP* = object of ESynch @@ -97,10 +100,14 @@ proc FTPClient*(address: string, port = TPort(21), result.isAsync = false result.dsockConnected = false + result.csock = socket() -proc getDSock(ftp: var TFTPClient): TSocket = +proc getDSock(ftp: PFTPClient): TSocket = if ftp.isAsync: return ftp.asyncDSock else: return ftp.dsock +proc getCSock(ftp: PFTPClient): TSocket = + if ftp.isAsync: return ftp.asyncCSock else: return ftp.csock + template blockingOperation(sock: TSocket, body: stmt) = if ftp.isAsync: sock.setBlocking(true) @@ -108,15 +115,15 @@ template blockingOperation(sock: TSocket, body: stmt) = if ftp.isAsync: sock.setBlocking(false) -proc expectReply(ftp: var TFTPClient): TaintedString = +proc expectReply(ftp: PFTPClient): TaintedString = result = TaintedString"" - blockingOperation(ftp.csock): - if not ftp.csock.recvLine(result): setLen(result.string, 0) + blockingOperation(ftp.getCSock()): + if not ftp.getCSock().recvLine(result): setLen(result.string, 0) -proc send*(ftp: var TFTPClient, m: string): TaintedString = +proc send*(ftp: PFTPClient, m: string): TaintedString = ## Send a message to the server, and wait for a primary reply. ## ``\c\L`` is added for you. - ftp.csock.send(m & "\c\L") + ftp.getCSock().send(m & "\c\L") return ftp.expectReply() proc assertReply(received: TaintedString, expected: string) = @@ -132,8 +139,8 @@ proc assertReply(received: TaintedString, expected: varargs[string]) = "Expected reply '$1' got: $2" % [expected.join("' or '"), received.string]) -proc createJob(ftp: var TFTPClient, - prc: proc (ftp: var TFTPClient, async: bool): bool {.nimcall.}, +proc createJob(ftp: PFTPClient, + prc: proc (ftp: PFTPClient, async: bool): bool {.nimcall.}, cmd: FTPJobType) = if ftp.jobInProgress: raise newException(EFTP, "Unable to do two jobs at once.") @@ -147,7 +154,7 @@ proc createJob(ftp: var TFTPClient, of JRetr, JStore: ftp.job.toStore = "" -proc deleteJob(ftp: var TFTPClient) = +proc deleteJob(ftp: PFTPClient) = assert ftp.jobInProgress ftp.jobInProgress = false case ftp.job.typ @@ -155,12 +162,63 @@ proc deleteJob(ftp: var TFTPClient) = ftp.job.lines = "" of JRetr, JStore: ftp.job.file.close() + if ftp.isAsync: + ftp.asyncDSock.close() + else: + ftp.dsock.close() -proc pasv(ftp: var TFTPClient) = +proc handleTask(s: PAsyncSocket, ftp: PFTPClient) = + if ftp.jobInProgress: + if ftp.job.typ in {JRetr, JStore}: + if epochTime() - ftp.job.lastProgressReport >= 1.0: + var r: TFTPEvent + ftp.job.lastProgressReport = epochTime() + r.typ = EvTransferProgress + r.bytesTotal = ftp.job.total + r.bytesFinished = ftp.job.progress + r.speed = ftp.job.oneSecond + r.filename = ftp.job.filename + r.currentJob = ftp.job.typ + ftp.job.oneSecond = 0 + ftp.handleEvent(PAsyncFTPClient(ftp), r) + +proc handleWrite(s: PAsyncSocket, ftp: PFTPClient) = + if ftp.jobInProgress: + if ftp.job.typ == JStore: + assert (not ftp.job.prc(ftp, true)) + +proc handleConnect(s: PAsyncSocket, ftp: PFTPClient) = + ftp.dsockConnected = true + assert(ftp.jobInProgress) + if ftp.job.typ == JStore: + s.setHandleWrite(proc (s: PAsyncSocket) = handleWrite(s, ftp)) + else: + s.delHandleWrite() + +proc handleRead(s: PAsyncSocket, ftp: PFTPClient) = + assert ftp.jobInProgress + assert ftp.job.typ != JStore + # This can never return true, because it shouldn't check for code + # 226 from csock. + assert(not ftp.job.prc(ftp, true)) + +proc pasv(ftp: PFTPClient) = ## Negotiate a data connection. if not ftp.isAsync: ftp.dsock = socket() - else: ftp.asyncDSock = AsyncSocket() + else: + ftp.asyncDSock = AsyncSocket() + ftp.asyncDSock.handleRead = + proc (s: PAsyncSocket) = + handleRead(s, ftp) + ftp.asyncDSock.handleConnect = + proc (s: PAsyncSocket) = + handleConnect(s, ftp) + ftp.asyncDSock.handleTask = + proc (s: PAsyncSocket) = + handleTask(s, ftp) + ftp.disp.register(ftp.asyncDSock) + var pasvMsg = ftp.send("PASV").string.strip.TaintedString assertReply(pasvMsg, "227") var betweenParens = captureBetween(pasvMsg.string, '(', ')') @@ -178,13 +236,12 @@ proc pasv(ftp: var TFTPClient) = proc normalizePathSep(path: string): string = return replace(path, '\\', '/') -proc connect*(ftp: var TFTPClient) = +proc connect*(ftp: PFTPClient) = ## Connect to the FTP server specified by ``ftp``. if ftp.isAsync: - ftp.asyncCSock = AsyncSocket() + blockingOperation(ftp.asyncCSock): + ftp.asyncCSock.connect(ftp.address, ftp.port) else: - ftp.csock = socket() - blockingOperation(ftp.csock): ftp.csock.connect(ftp.address, ftp.port) # TODO: Handle 120? or let user handle it. @@ -196,21 +253,21 @@ proc connect*(ftp: var TFTPClient) = if ftp.pass != "": assertReply ftp.send("PASS " & ftp.pass), "230" -proc pwd*(ftp: var TFTPClient): string = +proc pwd*(ftp: PFTPClient): string = ## Returns the current working directory. var wd = ftp.send("PWD") assertReply wd, "257" return wd.string.captureBetween('"') # " -proc cd*(ftp: var TFTPClient, dir: string) = +proc cd*(ftp: PFTPClient, dir: string) = ## Changes the current directory on the remote FTP server to ``dir``. assertReply ftp.send("CWD " & dir.normalizePathSep), "250" -proc cdup*(ftp: var TFTPClient) = +proc cdup*(ftp: PFTPClient) = ## Changes the current directory to the parent of the current directory. assertReply ftp.send("CDUP"), "200" -proc getLines(ftp: var TFTPClient, async: bool = false): bool = +proc getLines(ftp: PFTPClient, async: bool = false): bool = ## Downloads text data in ASCII mode ## Returns true if the download is complete. ## It doesn't if `async` is true, because it doesn't check for 226 then. @@ -223,14 +280,14 @@ proc getLines(ftp: var TFTPClient, async: bool = false): bool = ftp.dsockConnected = False if not async: - var readSocks: seq[TSocket] = @[ftp.csock] + var readSocks: seq[TSocket] = @[ftp.getCSock()] # This is only needed here. Asyncio gets this socket... - blockingOperation(ftp.csock): - if readSocks.select(1) != 0 and ftp.csock notin readSocks: + blockingOperation(ftp.getCSock()): + if readSocks.select(1) != 0 and ftp.getCSock() notin readSocks: assertReply ftp.expectReply(), "226" return true -proc listDirs*(ftp: var TFTPClient, dir: string = "", +proc listDirs*(ftp: PFTPClient, dir: string = "", async = false): seq[string] = ## Returns a list of filenames in the given directory. If ``dir`` is "", ## the current directory is used. If ``async`` is true, this @@ -248,7 +305,7 @@ proc listDirs*(ftp: var TFTPClient, dir: string = "", ftp.deleteJob() else: return @[] -proc fileExists*(ftp: var TFTPClient, file: string): bool {.deprecated.} = +proc fileExists*(ftp: PFTPClient, file: string): bool {.deprecated.} = ## **Deprecated since version 0.9.0:** Please use ``existsFile``. ## ## Determines whether ``file`` exists. @@ -259,7 +316,7 @@ proc fileExists*(ftp: var TFTPClient, file: string): bool {.deprecated.} = for f in items(files): if f.normalizePathSep == file.normalizePathSep: return true -proc existsFile*(ftp: var TFTPClient, file: string): bool = +proc existsFile*(ftp: PFTPClient, file: string): bool = ## Determines whether ``file`` exists. ## ## Warning: This function may block. Especially on directories with many @@ -268,7 +325,7 @@ proc existsFile*(ftp: var TFTPClient, file: string): bool = for f in items(files): if f.normalizePathSep == file.normalizePathSep: return true -proc createDir*(ftp: var TFTPClient, dir: string, recursive: bool = false) = +proc createDir*(ftp: PFTPClient, dir: string, recursive: bool = false) = ## 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 @@ -285,7 +342,7 @@ proc createDir*(ftp: var TFTPClient, dir: string, recursive: bool = false) = previousDirs.add('/') assertReply reply, "257" -proc chmod*(ftp: var TFTPClient, path: string, +proc chmod*(ftp: PFTPClient, path: string, permissions: set[TFilePermission]) = ## Changes permission of ``path`` to ``permissions``. var userOctal = 0 @@ -307,7 +364,7 @@ proc chmod*(ftp: var TFTPClient, path: string, assertReply ftp.send("SITE CHMOD " & perm & " " & path.normalizePathSep), "200" -proc list*(ftp: var TFTPClient, dir: string = "", async = false): string = +proc list*(ftp: PFTPClient, dir: string = "", async = false): string = ## 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 @@ -324,7 +381,7 @@ proc list*(ftp: var TFTPClient, dir: string = "", async = false): string = else: return "" -proc retrText*(ftp: var TFTPClient, file: string, async = false): string = +proc retrText*(ftp: PFTPClient, file: string, async = false): string = ## Retrieves ``file``. File must be ASCII text. ## If ``async`` is true, this function will return immediately and ## it will be your job to call ``poll`` to progress this operation. @@ -339,7 +396,7 @@ proc retrText*(ftp: var TFTPClient, file: string, async = false): string = else: return "" -proc getFile(ftp: var TFTPClient, async = false): bool = +proc getFile(ftp: PFTPClient, async = false): bool = if ftp.dsockConnected: var r = "".TaintedString var returned = false @@ -358,13 +415,13 @@ proc getFile(ftp: var TFTPClient, async = false): bool = ftp.dsockConnected = False if not async: - var readSocks: seq[TSocket] = @[ftp.csock] - blockingOperation(ftp.csock): - if readSocks.select(1) != 0 and ftp.csock notin readSocks: + var readSocks: seq[TSocket] = @[ftp.getCSock()] + blockingOperation(ftp.getCSock()): + if readSocks.select(1) != 0 and ftp.getCSock() notin readSocks: assertReply ftp.expectReply(), "226" return true -proc retrFile*(ftp: var TFTPClient, file, dest: string, async = false) = +proc retrFile*(ftp: PFTPClient, file, dest: string, async = false) = ## 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 given by ``poll`` when the download is finished, @@ -388,7 +445,7 @@ proc retrFile*(ftp: var TFTPClient, file, dest: string, async = false) = while not ftp.job.prc(ftp, false): nil ftp.deleteJob() -proc doUpload(ftp: var TFTPClient, async = false): bool = +proc doUpload(ftp: PFTPClient, async = false): bool = if ftp.dsockConnected: if ftp.job.toStore.len() > 0: assert(async) @@ -403,7 +460,7 @@ proc doUpload(ftp: var TFTPClient, async = false): bool = setLen(s, len) if len == 0: # File finished uploading. - getDSock(ftp).close() + if ftp.isAsync: ftp.asyncDSock.close() else: ftp.dsock.close() ftp.dsockConnected = false if not async: @@ -420,7 +477,7 @@ proc doUpload(ftp: var TFTPClient, async = false): bool = ftp.job.progress.inc(len) ftp.job.oneSecond.inc(len) -proc store*(ftp: var TFTPClient, file, dest: string, async = false) = +proc store*(ftp: PFTPClient, file, dest: string, async = false) = ## Uploads ``file`` to ``dest`` on the remote FTP server. Usage of this ## function asynchronously is recommended to view the progress of ## the download. @@ -439,26 +496,16 @@ proc store*(ftp: var TFTPClient, file, dest: string, async = false) = while not ftp.job.prc(ftp, false): nil ftp.deleteJob() -proc close*(ftp: var TFTPClient) = +proc close*(ftp: PFTPClient) = ## Terminates the connection to the server. assertReply ftp.send("QUIT"), "221" if ftp.jobInProgress: ftp.deleteJob() - ftp.csock.close() - getDSock(ftp).close() - -proc handleTask(s: PAsyncSocket, ftp: PAsyncFTPClient) = - if ftp.jobInProgress: - if ftp.job.typ in {JRetr, JStore}: - if epochTime() - ftp.job.lastProgressReport >= 1.0: - var r: TFTPEvent - ftp.job.lastProgressReport = epochTime() - r.typ = EvTransferProgress - r.bytesTotal = ftp.job.total - r.bytesFinished = ftp.job.progress - r.speed = ftp.job.oneSecond - r.filename = ftp.job.filename - ftp.job.oneSecond = 0 - ftp.handleEvent(ftp[], r) + if ftp.isAsync: + ftp.asyncCSock.close() + ftp.asyncDSock.close() + else: + ftp.csock.close() + ftp.dsock.close() discard """proc getSocket(h: PObject): tuple[info: TInfo, sock: TSocket] = result = (SockIdle, InvalidSocket) @@ -470,51 +517,27 @@ discard """proc getSocket(h: PObject): tuple[info: TInfo, sock: TSocket] = result = (ftp.dsockStatus, ftp.dsock) else: result = (SockIdle, ftp.dsock)""" -proc handleWrite(s: PAsyncSocket, ftp: PAsyncFTPClient) = - if ftp.jobInProgress: - if ftp.job.typ == JStore: - assert (not ftp.job.prc(ftp[], true)) - proc csockHandleRead(s: PAsyncSocket, ftp: PAsyncFTPClient) = - assert(ftp.jobInProgress) - assertReply ftp[].expectReply(), "226" # Make sure the transfer completed. - var r: TFTPEvent - case ftp.job.typ - of JRetrText: - r.typ = EvLines - r.lines = ftp.job.lines - of JRetr: - r.typ = EvRetr - r.filename = ftp.job.filename - if ftp.job.progress != ftp.job.total: - raise newException(EFTP, "Didn't download full file.") - of JStore: - r.typ = EvStore - r.filename = ftp.job.filename - if ftp.job.progress != ftp.job.total: - raise newException(EFTP, "Didn't upload full file.") - ftp[].deleteJob() - # Unregister asyncCSock - ftp.disp.unregister(ftp.asyncCSockID) - ftp.asyncCSockID = nil - - ftp.handleEvent(ftp[], r) - -proc handleConnect(s: PAsyncSocket, ftp: PAsyncFTPClient) = - ftp.dsockConnected = true - assert(ftp.jobInProgress) - if ftp.job.typ == JStore: - s.setHandleWrite(proc (s: PAsyncSocket) = handleWrite(s, ftp)) - else: - s.delHandleWrite() - # Wrap c sock in a PAsyncSocket and add it to dispatcher. - assert ftp.disp != nil - assert ftp.asyncCSockID == nil - ftp.asyncCSock = ftp.csock.toAsyncSocket(state = SockConnected) - ftp.asyncCSock.handleRead = - proc (s: PAsyncSocket) = - csockHandleRead(s, ftp) - ftp.asyncCSockID = ftp.disp.register(ftp.asyncCSock) + if ftp.jobInProgress: + assertReply ftp.expectReply(), "226" # Make sure the transfer completed. + var r: TFTPEvent + case ftp.job.typ + of JRetrText: + r.typ = EvLines + r.lines = ftp.job.lines + of JRetr: + r.typ = EvRetr + r.filename = ftp.job.filename + if ftp.job.progress != ftp.job.total: + raise newException(EFTP, "Didn't download full file.") + of JStore: + r.typ = EvStore + r.filename = ftp.job.filename + if ftp.job.progress != ftp.job.total: + raise newException(EFTP, "Didn't upload full file.") + ftp.deleteJob() + + ftp.handleEvent(ftp, r) discard """proc handleConnect(h: PObject) = var ftp = PAsyncFTPClient(h) @@ -525,13 +548,6 @@ discard """proc handleConnect(h: PObject) = else: ftp.dele.mode = MReadable""" -proc handleRead(s: PAsyncSocket, ftp: PAsyncFTPClient) = - assert ftp.jobInProgress - assert ftp.job.typ != JStore - # This can never return true, because it shouldn't check for code - # 226 from csock. - assert(not ftp.job.prc(ftp[], true)) - discard """proc handleRead(h: PObject) = var ftp = PAsyncFTPClient(h) assert(ftp.jobInProgress) @@ -551,74 +567,78 @@ discard """proc csockGetSocket(h: PObject): tuple[info: TInfo, sock: TSocket] = proc AsyncFTPClient*(address: string, port = TPort(21), user, pass = "", - handleEvent: proc (ftp: var TAsyncFTPClient, ev: TFTPEvent) {.closure.} = - (proc (ftp: var TAsyncFTPClient, ev: TFTPEvent) = nil)): PAsyncFTPClient = + handleEvent: proc (ftp: PAsyncFTPClient, ev: TFTPEvent) {.closure.} = + (proc (ftp: PAsyncFTPClient, ev: TFTPEvent) = nil)): PAsyncFTPClient = ## Create a ``PAsyncFTPClient`` object. ## ## Use this if you want to use asyncio's dispatcher. - new(result) - result.user = user - result.pass = pass - result.address = address - result.port = port - result.isAsync = true - result.dsockConnected = false - result.handleEvent = handleEvent + var dres: PAsyncFTPClient + new(dres) + dres.user = user + dres.pass = pass + dres.address = address + dres.port = port + dres.isAsync = true + dres.dsockConnected = false + dres.handleEvent = handleEvent + dres.asyncCSock = AsyncSocket() + dres.asyncCSock.handleRead = + proc (s: PAsyncSocket) = + csockHandleRead(s, dres) + result = dres -proc register*(d: PDispatcher, ftp: PAsyncFTPClient) = +proc register*(d: PDispatcher, ftp: PAsyncFTPClient): PDelegate {.discardable.} = ## Registers ``ftp`` with dispatcher ``d``. assert ftp.isAsync ftp.disp = d - ftp.asyncDSock.handleRead = - proc (s: PAsyncSocket) = - handleRead(s, ftp) - ftp.asyncDSock.handleConnect = - proc (s: PAsyncSocket) = - handleConnect(s, ftp) - ftp.asyncDSock.handleTask = - proc (s: PAsyncSocket) = - handleTask(s, ftp) - d.register(ftp.asyncDSock) + return ftp.disp.register(ftp.asyncCSock) when isMainModule: - var ftp = FTPClient("picheta.me", user = "blah", pass = "sd") - ftp.connect() - echo ftp.pwd() - echo ftp.list() - echo("uploading") - ftp.store("payload.avi", "payload.avi", async = false) - discard """ - while True: - var event: TFTPEvent - if ftp.poll(event): + var d = newDispatcher() + let hev = + proc (ftp: PAsyncFTPClient, event: TFTPEvent) = case event.typ of EvStore: echo("Upload finished!") - break + ftp.retrFile("payload.JPG", "payload2.JPG", async = true) of EvTransferProgress: var time: int64 = -1 if event.speed != 0: time = (event.bytesTotal - event.bytesFinished) div event.speed + echo(event.currentJob) echo(event.speed div 1000, " kb/s. - ", event.bytesFinished, "/", event.bytesTotal, " - ", time, " seconds") - - else: assert(false) - """ - echo("Upload complete") - ftp.retrFile("payload.avi", "payload2.avi", async = false) - discard """ - while True: - var event: TFTPEvent - if ftp.poll(event): - case event.typ + echo(d.len) of EvRetr: echo("Download finished!") - break - of EvTransferProgress: - echo(event.speed div 1000, " kb/s") + ftp.close() + echo d.len else: assert(false) - """ + var ftp = AsyncFTPClient("picheta.me", user = "test", pass = "asf", handleEvent = hev) + + d.register(ftp) + d.len.echo() + ftp.connect() + echo "connected" + ftp.store("payload.JPG", "payload.JPG", async = true) + d.len.echo() + echo "uploading..." + while true: + if not d.poll(): break + + +when isMainModule and false: + var ftp = FTPClient("picheta.me", user = "asdasd", pass = "asfwq") + ftp.connect() + echo ftp.pwd() + echo ftp.list() + echo("uploading") + ftp.store("payload.JPG", "payload.JPG", async = false) + + echo("Upload complete") + ftp.retrFile("payload.JPG", "payload2.JPG", async = false) + echo("Download complete") sleep(5000) ftp.close() diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 7b1ef818b..188fcb5d8 100755 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -533,7 +533,7 @@ proc accept*(server: TSocket, client: var TSocket) = proc acceptAddr*(server: TSocket): tuple[client: TSocket, address: string] {.deprecated.} = ## Slightly different version of ``acceptAddr``. ## - ## **Warning**: This function is now deprecated, you shouldn't use it! + ## **Deprecated since version 0.9.0:** Please use the function above. var client: TSocket new(client) var address = "" @@ -541,7 +541,7 @@ proc acceptAddr*(server: TSocket): tuple[client: TSocket, address: string] {.dep return (client, address) proc accept*(server: TSocket): TSocket {.deprecated.} = - ## **Warning**: This function is now deprecated, you shouldn't use it! + ## **Deprecated since version 0.9.0:** Please use the function above. new(result) var address = "" acceptAddr(server, result, address) |