File transfers
This commit is contained in:
parent
7b3b25ff15
commit
1071e63d1c
|
@ -52,31 +52,79 @@ when defined(spry):
|
||||||
discard result.evalRoot("""[loadFile: "blobs.sy"]""")
|
discard result.evalRoot("""[loadFile: "blobs.sy"]""")
|
||||||
|
|
||||||
when defined(tox) and defined(spry):
|
when defined(tox) and defined(spry):
|
||||||
|
type IngestTransfer = object
|
||||||
|
name: string
|
||||||
|
stream: IngestStream
|
||||||
|
size, pos: uint64
|
||||||
|
|
||||||
|
proc process(
|
||||||
|
t: var IngestTransfer; tox: Tox; friend: Friend; file: FileTransfer;
|
||||||
|
pos: uint64; data: pointer; size: int): bool =
|
||||||
|
## Process transfer data, return true if transfer is complete
|
||||||
|
if t.pos != pos:
|
||||||
|
cancel t.stream
|
||||||
|
tox.control(friend, file, TOX_FILE_CONTROL_CANCEL)
|
||||||
|
discard tox.send(friend, """stream is at position $# but you sent $#""" % [$t.pos, $pos])
|
||||||
|
result = true
|
||||||
|
else:
|
||||||
|
waitFor t.stream.ingest(data, size)
|
||||||
|
t.pos.inc size
|
||||||
|
if t.pos >= t.size:
|
||||||
|
let blobId, blobSize = waitFor t.stream.finish()
|
||||||
|
discard tox.send(friend, """$# $# $#""" % [t.name, $blobId, $blobSize])
|
||||||
|
result = true
|
||||||
|
|
||||||
|
type Transfer = uint64
|
||||||
|
proc `+`(friend: Friend; file: FileTransfer): Transfer =
|
||||||
|
(friend.Transfer shl 32) or file.Transfer
|
||||||
|
|
||||||
proc setupCallbacks(tox: Tox) =
|
proc setupCallbacks(tox: Tox) =
|
||||||
tox.onSelfConnectionStatus do (status: TOX_CONNECTION):
|
tox.onSelfConnectionStatus do (status: TOX_CONNECTION):
|
||||||
echo "self status is ", status
|
echo "self status is ", status
|
||||||
let
|
|
||||||
store = openStore()
|
|
||||||
spry = newSpry(store)
|
|
||||||
proc eval(code: string): string {.gcsafe.} =
|
|
||||||
$(spry.evalRoot(code))
|
|
||||||
tox.onFriendMessage do (friend: Friend; msg: string; kind: TOX_MESSAGE_TYPE):
|
|
||||||
try:
|
|
||||||
if kind == TOX_MESSAGE_TYPE_NORMAL:
|
|
||||||
tox.typing(friend, true)
|
|
||||||
let res = eval("[" & msg & "]")
|
|
||||||
tox.typing(friend, false)
|
|
||||||
discard tox.send(friend, $res, TOX_MESSAGE_TYPE_ACTION)
|
|
||||||
except:
|
|
||||||
discard tox.send(friend, getCurrentExceptionMsg())
|
|
||||||
|
|
||||||
tox.onFriendRequest do (key: PublicKey; msg: string):
|
tox.onFriendRequest do (key: PublicKey; msg: string):
|
||||||
echo "friend request from ", key, ", ", msg
|
echo "friend request from ", key, ", ", msg
|
||||||
discard tox.addFriendNoRequest(key)
|
discard tox.addFriendNoRequest(key)
|
||||||
|
block:
|
||||||
|
let
|
||||||
|
store = openStore()
|
||||||
|
spry = newSpry(store)
|
||||||
|
transfers = newTable[Transfer, IngestTransfer](16)
|
||||||
|
tox.onFriendMessage do (friend: Friend; msg: string; kind: TOX_MESSAGE_TYPE):
|
||||||
|
try:
|
||||||
|
if kind == TOX_MESSAGE_TYPE_NORMAL:
|
||||||
|
tox.typing(friend, true)
|
||||||
|
let res = spry.evalRoot("[" & msg & "]")
|
||||||
|
tox.typing(friend, false)
|
||||||
|
discard tox.send(friend, $res, TOX_MESSAGE_TYPE_ACTION)
|
||||||
|
except:
|
||||||
|
discard tox.send(friend, getCurrentExceptionMsg())
|
||||||
|
tox.onFileRecv do (friend: Friend; file: FileTransfer; kind: uint32; size: uint64; filename: string):
|
||||||
|
case kind
|
||||||
|
of (uint32)TOX_FILE_KIND_AVATAR:
|
||||||
|
tox.control(friend, file, TOX_FILE_CONTROL_CANCEL)
|
||||||
|
else:
|
||||||
|
if transfers.len > 16:
|
||||||
|
tox.control(friend, file, TOX_FILE_CONTROL_CANCEL)
|
||||||
|
discard tox.send(friend, "too many transfers are pending")
|
||||||
|
else:
|
||||||
|
let msg = """you are trying to send me "$#", type $#, size $#""" %
|
||||||
|
[filename, $kind, $size]
|
||||||
|
discard tox.send(friend, msg)
|
||||||
|
transfers[friend+file] = IngestTransfer(
|
||||||
|
name: filename,
|
||||||
|
stream: store.openIngestStream(size.BiggestInt),
|
||||||
|
size: size)
|
||||||
|
tox.control(friend, file, TOX_FILE_CONTROL_RESUME)
|
||||||
|
tox.onFileRecvChunk do (friend: Friend; file: FileTransfer; pos: uint64; data: pointer; size: int):
|
||||||
|
try:
|
||||||
|
if transfers[friend+file].process(tox, friend, file, pos, data, size):
|
||||||
|
transfers.del(friend+file)
|
||||||
|
except:
|
||||||
|
discard tox.send(friend, getCurrentExceptionMsg(), TOX_MESSAGE_TYPE_ACTION)
|
||||||
|
|
||||||
tox.name = "blobbot"
|
tox.name = "blobbot"
|
||||||
echo "callbacks set"
|
echo "/connect 127.0.0.1 ", tox.udpPort, " ", tox.dhtId
|
||||||
echo "Tox address: ", tox.address
|
echo "/add ", tox.address
|
||||||
echo "Tox DHT: ", tox.udpPort, " ", tox.dhtId
|
|
||||||
|
|
||||||
proc toxMain() {.async.} =
|
proc toxMain() {.async.} =
|
||||||
let tox = newTox do (o: Options):
|
let tox = newTox do (o: Options):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user