Add Tox-based Spry interpreter
parent
358a7389a3
commit
fbf62c53ac
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
_meta = {
|
||||
name = 'Blobs
|
||||
version = "1.0"
|
||||
description = "Blobs module"
|
||||
}
|
||||
|
||||
cbor = $..blobCbor
|
||||
commit = $..blobCommit
|
||||
hex = $..blobHex
|
||||
ingest = $..blobIngest
|
||||
key = $..key
|
||||
load = $..blobLoad
|
||||
merge = $..blobMerge
|
||||
toBlobId = $..toBlobId
|
||||
}
|
|
@ -6,7 +6,7 @@ description = "Sets of named blobs"
|
|||
license = "AGPLv3"
|
||||
srcDir = "src"
|
||||
|
||||
requires "nim >= 0.18.0", "cbor >= 0.5.2", "siphash", "spryvm"
|
||||
requires "nim >= 0.18.0", "cbor >= 0.5.2", "siphash", "spryvm", "toxcore"
|
||||
|
||||
bin = @["blobset", "blobserver"]
|
||||
skipFiles = @["blobset.nim", "blobserver.nim"]
|
||||
|
|
102
src/blobset.nim
102
src/blobset.nim
|
@ -6,13 +6,16 @@ import cbor
|
|||
import ./blobsets, ./blobsets/filestores,
|
||||
./blobsets/httpservers, ./blobsets/httpstores
|
||||
|
||||
when defined(tox):
|
||||
import toxcore
|
||||
|
||||
# Basic Spry
|
||||
when defined(spry):
|
||||
import spryvm/spryvm
|
||||
|
||||
# Spry extra modules
|
||||
import spryvm/sprycore, spryvm/spryextend, spryvm/sprymath, spryvm/spryos, spryvm/spryio,
|
||||
spryvm/spryoo, spryvm/sprystring, spryvm/sprymodules, spryvm/spryreflect, spryvm /sprymemfile,
|
||||
spryvm/spryoo, spryvm/sprystring, spryvm/sprymodules, spryvm/spryreflect, spryvm/sprymemfile,
|
||||
spryvm/spryblock,
|
||||
./blobsets/spryblobs
|
||||
|
||||
|
@ -20,18 +23,77 @@ import os, strutils
|
|||
when defined(readLine):
|
||||
import rdstdin, linenoise
|
||||
|
||||
#when defined(genode):
|
||||
# import dagfsclient
|
||||
|
||||
#else:
|
||||
# import ./blobsets/tcp
|
||||
|
||||
proc openStore(): BlobStore =
|
||||
const key = "BLOB_STORE_URL"
|
||||
let url = os.getEnv key
|
||||
var url = os.getEnv key
|
||||
if url == "":
|
||||
quit(key & " not set in environment")
|
||||
newHttpStore(url)
|
||||
url = "/tmp/blobs"
|
||||
#quit(key & " not set in environment")
|
||||
if url.startsWith "http://":
|
||||
newHttpStore(url)
|
||||
else:
|
||||
newFileStore(url)
|
||||
|
||||
when defined(spry):
|
||||
proc newSpry(store: BlobStore): Interpreter =
|
||||
result = newInterpreter()
|
||||
result.addCore()
|
||||
result.addExtend()
|
||||
result.addMath()
|
||||
result.addOS()
|
||||
result.addIO()
|
||||
result.addOO()
|
||||
result.addString()
|
||||
result.addModules()
|
||||
result.addReflect()
|
||||
result.addMemfile()
|
||||
result.addBlock()
|
||||
result.addBlobSets(store)
|
||||
discard result.evalRoot("""[loadFile: "blobs.sy"]""")
|
||||
|
||||
when defined(tox) and defined(spry):
|
||||
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)
|
||||
tox.name = "blobbot"
|
||||
echo "callbacks set"
|
||||
echo "Tox address: ", tox.address
|
||||
echo "Tox DHT: ", tox.udpPort, " ", tox.dhtId
|
||||
|
||||
proc toxMain() {.async.} =
|
||||
let tox = newTox do (o: Options):
|
||||
o.ipv6Enabled = false
|
||||
o.localDiscoveryEnabled = true
|
||||
o.holePunchingEnabled = false
|
||||
var saveData = ""
|
||||
try: saveData = readFile "tox.save"
|
||||
except: discard
|
||||
if saveData != "":
|
||||
o.saveData = saveData
|
||||
o.saveDataType = TOX_SAVEDATA_TYPE_TOX_SAVE
|
||||
writeFile "tox.save", tox.saveData
|
||||
setupCallbacks(tox)
|
||||
while not tox.isClosed:
|
||||
iterate tox
|
||||
await sleepAsync(tox.iterationInterval)
|
||||
|
||||
proc serverMain(): Future[void] =
|
||||
let
|
||||
|
@ -835,19 +897,7 @@ proc getLine(prompt: string): string =
|
|||
|
||||
when defined(spry):
|
||||
proc spryMain() =
|
||||
let spry = newInterpreter()
|
||||
spry.addCore()
|
||||
spry.addExtend()
|
||||
spry.addMath()
|
||||
spry.addOS()
|
||||
spry.addIO()
|
||||
spry.addOO()
|
||||
spry.addString()
|
||||
spry.addModules()
|
||||
spry.addReflect()
|
||||
spry.addMemfile()
|
||||
spry.addBlock()
|
||||
spry.addBlobSets()
|
||||
let spry = newSpry(openStore())
|
||||
var
|
||||
lines, stashed, fileLines = newSeq[string]()
|
||||
suspended: bool = true
|
||||
|
@ -926,4 +976,10 @@ when isMainModule:
|
|||
quit "not compiled with Spry interpreter"
|
||||
of "check": waitFor checkMain()
|
||||
of "replicate": waitFor replicateMain()
|
||||
of "tox":
|
||||
when defined(tox) and defined(spry):
|
||||
#waitFor toxReplicateMain()
|
||||
waitFor toxMain()
|
||||
else:
|
||||
quit "not compiled with Tox node"
|
||||
else: quit("no such subcommand " & cmd)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# Disable this to use only primitive stdin
|
||||
-d:readLine
|
||||
--nilseqs:on
|
||||
-d:spry
|
||||
-d:tox
|
||||
|
|
|
@ -10,10 +10,10 @@ type BlobIdSpryNode* = ref object of Value
|
|||
type BlobSetSpryNode* = ref object of Value
|
||||
set*: BlobSet
|
||||
|
||||
method eval*(self: BlobIdSpryNode|BlobSetSpryNode; spry: Interpreter): Node = self
|
||||
method eval*(self: BlobIdSpryNode; spry: Interpreter): Node = self
|
||||
method eval*(self: BlobSetSpryNode; spry: Interpreter): Node = self
|
||||
|
||||
method `$`*(self: BlobIdSpryNode): string = $self.id
|
||||
|
||||
method `$`*(self: BlobSetSpryNode): string = "<BlobSet>"
|
||||
|
||||
type BlobStoreNode* = ref object of Value
|
||||
|
@ -24,21 +24,16 @@ type BlobStoreNode* = ref object of Value
|
|||
|
||||
proc insertPath(store: BlobStore; bs: BlobSet; kind: PathComponent; path: string): BlobSet =
|
||||
result = bs
|
||||
try:
|
||||
case kind
|
||||
of pcFile, pcLinkToFile:
|
||||
var path = normalizedPath path
|
||||
let (id, size) = waitFor store.ingestFile(path)
|
||||
path.removePrefix(getCurrentDir())
|
||||
path.removePrefix("/")
|
||||
result = waitFor insert(store, result, path, id, size)
|
||||
writeLine(stdout, id, align($size, 11), " ", path)
|
||||
of pcDir, pcLinkToDir:
|
||||
for kind, subPath in path.walkDir:
|
||||
result = store.insertPath(result, kind, subPath)
|
||||
except:
|
||||
let e = getCurrentException()
|
||||
writeLine(stderr, "failed to ingest '", path, "', ", e.msg)
|
||||
case kind
|
||||
of pcFile, pcLinkToFile:
|
||||
var path = normalizedPath path
|
||||
let (id, size) = waitFor store.ingestFile(path)
|
||||
path.removePrefix(getCurrentDir())
|
||||
path.removePrefix("/")
|
||||
result = waitFor insert(store, result, path, id, size)
|
||||
of pcDir, pcLinkToDir:
|
||||
for kind, subPath in path.walkDir:
|
||||
result = store.insertPath(result, kind, subPath)
|
||||
|
||||
proc getSet(env: BlobStoreNode; path: string): BlobSet =
|
||||
result = env.sets.getOrDefault(path)
|
||||
|
@ -53,41 +48,48 @@ proc ingestBlobs(env: BlobStoreNode; path: string): BlobSetSpryNode =
|
|||
BlobSetSpryNode(set: bs)
|
||||
|
||||
# Spry Blobset module
|
||||
proc addBlobSets*(spry: Interpreter) =
|
||||
proc addBlobSets*(spry: Interpreter; store: BlobStore) =
|
||||
|
||||
nimMeth "ingestBlobs":
|
||||
var env = BlobStoreNode(evalArgInfix(spry))
|
||||
let env = BlobStoreNode(
|
||||
store: store,
|
||||
blobs: initTable[string, tuple[id: BlobId, size: BiggestInt]](),
|
||||
sets: initTable[string, BlobSet]())
|
||||
|
||||
nimMeth "blobMerge":
|
||||
let
|
||||
a = BlobSetSpryNode(evalArgInfix(spry))
|
||||
b = BlobSetSpryNode(evalArg(spry))
|
||||
c = env.store.union(a.set, b.set)
|
||||
BlobSetSpryNode(set: c)
|
||||
|
||||
nimFunc "blobLoad":
|
||||
let
|
||||
node = BlobIdSpryNode(evalArg(spry))
|
||||
set = waitFor env.store.load(node.id)
|
||||
BlobSetSpryNode(set: set)
|
||||
|
||||
nimFunc "blobIngest":
|
||||
let path = StringVal(evalArg(spry)).value
|
||||
result = ingestBlobs(env, path)
|
||||
|
||||
nimFunc "newBlobStore":
|
||||
proc newStore(s: string): BlobStore =
|
||||
if s.startsWith "http://": newHttpStore(s)
|
||||
else: newFileStore(s)
|
||||
let arg = StringVal(evalArg(spry)).value
|
||||
BlobStoreNode(
|
||||
store: newStore(arg),
|
||||
blobs: initTable[string, tuple[id: BlobId, size: BiggestInt]](),
|
||||
sets: initTable[string, BlobSet]())
|
||||
|
||||
nimFunc "toBlobId":
|
||||
let str = StringVal(evalArg(spry)).value
|
||||
BlobIdSpryNode(id: str.toBlobId)
|
||||
|
||||
nimFunc "cbor":
|
||||
nimFunc "blobCbor":
|
||||
let set = BlobSetSpryNode(evalArg(spry)).set
|
||||
newValue($toCbor(set))
|
||||
|
||||
nimFunc "commit":
|
||||
nimFunc "blobCommit":
|
||||
let
|
||||
env = BlobStoreNode(evalArgInfix(spry))
|
||||
set = BlobSetSpryNode(evalArg(spry)).set
|
||||
BlobSetSpryNode(set: waitFor env.store.commit(set))
|
||||
setNode = BlobSetSpryNode(evalArg(spry))
|
||||
coldSet = waitFor env.store.commit(setNode.set)
|
||||
BlobIdSpryNode(id: coldSet.setId)
|
||||
|
||||
nimFunc "hex":
|
||||
nimFunc "blobHex":
|
||||
let id = BlobIdSpryNode(evalArg(spry)).id
|
||||
newValue(id.toHex)
|
||||
|
||||
#nimFunc "key":
|
||||
# let str = StringVal(evalArg(spry)).value
|
||||
# newValue(str.toKey)
|
||||
nimFunc "key":
|
||||
let str = StringVal(evalArg(spry)).value
|
||||
newValue(str.toKey.int)
|
||||
|
|
Loading…
Reference in New Issue