Implement avatar status image
This commit is contained in:
parent
ec5017a8b8
commit
fb7359d89d
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
hqtoxbot
|
||||
result
|
||||
hqtoxbot.save
|
||||
avatar.png
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
import toxcore
|
||||
|
||||
import std/asyncdispatch, std/base64, std/json, std/httpclient, std/os, std/strutils
|
||||
import std/asyncdispatch, std/asyncfile, std/base64, std/json, std/httpclient,
|
||||
std/os, std/strutils, std/uri
|
||||
|
||||
{.passL: "-lcrypto".}
|
||||
|
||||
const
|
||||
readmeText = readFile "README.md"
|
||||
spaceApiUrl = "http://spaceapi.hq.c3d2.de:3000/spaceapi.json"
|
||||
shalterLockUrl = "http://172.22.99.204/door/lock"
|
||||
shalterUnlockUrl = "http://172.22.99.204/door/unlock"
|
||||
# These are IP addresses so the door can be unlocked without DNS
|
||||
saveFileName = "hqtoxbot.save"
|
||||
iconFilename = "avatar.png"
|
||||
adminIds = [
|
||||
toAddress "DF0AC9107E0A30E7201C6832B017AC836FBD1EDAC390EE99B68625D73C3FD929FB47F1872CA4"
|
||||
# Emery
|
||||
]
|
||||
|
||||
|
||||
proc bootstrap(bot: Tox) =
|
||||
const servers = [
|
||||
( "tox.neuland.technology",
|
||||
("tox.neuland.technology",
|
||||
"15E9C309CFCB79FDDF0EBA057DABB49FE15F3803B1BFF06536AE2E5BA5E4690E".toPublicKey
|
||||
)
|
||||
]
|
||||
|
@ -29,16 +35,48 @@ proc addAdmin(bot: Tox; id: Address) =
|
|||
except ToxError:
|
||||
discard
|
||||
|
||||
proc updateStatus(bot: Tox; http: AsyncHttpClient) {.async.} =
|
||||
proc sendAvatar(bot: Tox; friend: Friend) =
|
||||
discard bot.send(
|
||||
friend, TOX_FILE_KIND_AVATAR.uint32,
|
||||
iconFilename.getFileSize, iconFilename)
|
||||
|
||||
proc sendAvatarChunk(bot: Tox; friend: Friend; file: FileTransfer; pos: uint64;
|
||||
size: int) {.async.} =
|
||||
let iconFile = openAsync(iconFilename, fmRead)
|
||||
iconFile.setFilePos(pos.int64);
|
||||
let chunk = await iconFile.read(size)
|
||||
close iconFile
|
||||
bot.sendChunk(friend, file, pos, chunk)
|
||||
|
||||
proc updateAvatar(bot: Tox) =
|
||||
assert(iconFilename != "")
|
||||
for friend in bot.friends:
|
||||
if bot.connectionStatus(friend) != TOX_CONNECTION_NONE:
|
||||
bot.sendAvatar(friend)
|
||||
|
||||
proc updateStatus(bot: Tox) {.async.} =
|
||||
try:
|
||||
let
|
||||
http = newAsyncHttpClient()
|
||||
rsp = await http.get(spaceApiUrl)
|
||||
body = await rsp.body
|
||||
space = parseJson body
|
||||
status = $(space["status"])
|
||||
status = space["status"].getStr
|
||||
open = space["state"]["open"].getBool
|
||||
if bot.statusMessage != status:
|
||||
bot.statusMessage = unescape $(space["status"])
|
||||
bot.statusMessage = status
|
||||
if open:
|
||||
bot.status = TOX_USER_STATUS_NONE
|
||||
let iconUrl = space["icon"]["open"].getStr.parseUri
|
||||
await http.downloadFile($iconUrl, iconFilename)
|
||||
else:
|
||||
bot.status = TOX_USER_STATUS_AWAY
|
||||
let iconUrl = space["icon"]["closed"].getStr.parseUri
|
||||
await http.downloadFile($iconUrl, iconFilename)
|
||||
bot.updateAvatar()
|
||||
close http
|
||||
except:
|
||||
echo getCurrentExceptionMsg()
|
||||
bot.statusMessage = "status update failed"
|
||||
|
||||
type Command = enum
|
||||
|
@ -48,12 +86,11 @@ type Command = enum
|
|||
lock,
|
||||
readme,
|
||||
revoke,
|
||||
unlock,
|
||||
unlock
|
||||
|
||||
proc setup(bot: Tox) =
|
||||
let http = newAsyncHttpClient()
|
||||
addTimer(20*1000, oneshot = false) do (fd: AsyncFD) -> bool:
|
||||
asyncCheck updateStatus(bot, http)
|
||||
asyncCheck updateStatus(bot)
|
||||
|
||||
let schalterClient = newAsyncHttpClient()
|
||||
schalterClient.headers = newHttpHeaders()
|
||||
|
@ -64,9 +101,7 @@ proc setup(bot: Tox) =
|
|||
bot.onFriendConnectionStatus do (f: Friend; status: Connection):
|
||||
if status != TOX_CONNECTION_NONE:
|
||||
bot.invite(f, conference)
|
||||
|
||||
bot.onFriendReadReceipt do (f: friend; id; MessageId):
|
||||
discard """TODO some commands should be defered until a read receipt is acquired. Maybe just revoke."""
|
||||
bot.sendAvatar(f)
|
||||
|
||||
bot.onFriendMessage do (f: Friend; msg: string; kind: MessageType):
|
||||
proc reply(msg: string) =
|
||||
|
@ -114,16 +149,15 @@ proc setup(bot: Tox) =
|
|||
of invite:
|
||||
for id in words[1..words.high]:
|
||||
try:
|
||||
let
|
||||
address = id.toAddress
|
||||
other = bot.addFriend(address, "You have been invited to the $1 by $2 ($3)" % [ bot.name, bot.name(f), $bot.publicKey(f) ])
|
||||
bot.invite(other, conference)
|
||||
discard bot.addFriend(id.toAddress,
|
||||
"You have been invited to the $1 by $2 ($3)" % [bot.name,
|
||||
bot.name(f), $bot.publicKey(f)])
|
||||
except:
|
||||
reply(getCurrentExceptionMsg())
|
||||
|
||||
of lock:
|
||||
bot.typing(f, true)
|
||||
let fut = schalterClient.post("http://schalter.hq.c3d2.de/door/lock")
|
||||
let fut = schalterClient.post(shalterLockUrl)
|
||||
fut.addCallback do ():
|
||||
bot.typing(f, false)
|
||||
if fut.failed:
|
||||
|
@ -140,7 +174,7 @@ proc setup(bot: Tox) =
|
|||
|
||||
of unlock:
|
||||
bot.typing(f, true)
|
||||
let fut = schalterClient.post("http://schalter.hq.c3d2.de/door/unlock")
|
||||
let fut = schalterClient.post(shalterUnlockUrl)
|
||||
fut.addCallback do ():
|
||||
bot.typing(f, false)
|
||||
if fut.failed:
|
||||
|
@ -150,6 +184,10 @@ proc setup(bot: Tox) =
|
|||
except:
|
||||
reply(getCurrentExceptionMsg())
|
||||
|
||||
bot.onFileChunkRequest do (friend: Friend; file: FileTransfer; pos: uint64; size: int):
|
||||
if size != 0:
|
||||
asyncCheck bot.sendAvatarChunk(friend, file, pos, size)
|
||||
|
||||
proc newBot(name: string): Tox =
|
||||
result = newTox do (opts: Options):
|
||||
opts.localDiscoveryEnabled = true
|
||||
|
|
Loading…
Reference in New Issue
Block a user