File transfers
This commit is contained in:
parent
7b3b25ff15
commit
1071e63d1c
|
@ -52,31 +52,79 @@ when defined(spry):
|
|||
discard result.evalRoot("""[loadFile: "blobs.sy"]""")
|
||||
|
||||
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) =
|
||||
tox.onSelfConnectionStatus do (status: TOX_CONNECTION):
|
||||
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):
|
||||
echo "friend request from ", key, ", ", msg
|
||||
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"
|
||||
echo "callbacks set"
|
||||
echo "Tox address: ", tox.address
|
||||
echo "Tox DHT: ", tox.udpPort, " ", tox.dhtId
|
||||
echo "/connect 127.0.0.1 ", tox.udpPort, " ", tox.dhtId
|
||||
echo "/add ", tox.address
|
||||
|
||||
proc toxMain() {.async.} =
|
||||
let tox = newTox do (o: Options):
|
||||
|
|
Loading…
Reference in New Issue
Block a user