Arbitrary immutulation, not just videos

This commit is contained in:
Emery Hemingway 2023-09-05 23:44:26 +02:00
parent a8c13b8e72
commit ca3500cdad
7 changed files with 55 additions and 87 deletions

View File

@ -1,6 +1,6 @@
# video immutulator # The Immutulator
Rip from video silos into ERIS. Ingest files into ERIS.
It takes a bit of configuring. An example: It takes a bit of configuring. An example:
``` ```
@ -8,48 +8,61 @@ let ?ds = dataspace
<eris $ds> <eris $ds>
<bind <ref {oid: "eris" key: #x""}> $ds #f> <bind <ref {oid: "eris" key: #x""}> $ds #f>
<daemon video_immutulator { <daemon immutulator {
argv: ["/bin/video_immutulator"] argv: ["/bin/immutulator"]
protocol: application/syndicate protocol: application/syndicate
}> }>
? <eris ?dataspace> $dataspace [ ? <eris ?dataspace> $dataspace [
$dataspace ? <Observe <rec immutulation _ _ _ _> _> [ ; require the daemon when immutulating
$config <require-service <daemon video_immutulator>> $dataspace ? <Observe <rec immutulation _> _> [
$config <require-service <daemon immutulator>>
] ]
$dataspace ? <Observe <rec yt-dlp [<lit ?url> _]> _> [ ; resolve <immutulation-yt-dlp > from <immutulation >
$dataspace ? <Observe <rec immutulation-yt-dlp [<lit ?url> _ _ _]> _> [
; temporarily start yt-dlp
let ?id = <yt-dlp $url> let ?id = <yt-dlp $url>
$config <require-service <daemon $id>> $config <require-service <daemon $id>>
<daemon $id { ; translate the output of yt-dlp --dump-json
argv: [ $config ? <built json_translator ?translator _> [
"/bin/json_translator" <daemon $id {
"yt-dlp" argv: [
"--embed-subs" $translator
"--embed-metadata" "yt-dlp"
"--dump-json" "--embed-subs"
"--no-simulate" "--embed-metadata"
"--output" "/tmp/%(id)s.%(ext)s" "--dump-json"
$url "--no-simulate"
] "--output" "/tmp/%(id)s.%(ext)s"
protocol: application/syndicate $url
}> ]
protocol: application/syndicate
}>
]
$config ? <service-object <daemon $id> ?cap> [ $config ? <service-object <daemon $id> ?cap> [
$cap ? <recv ?json> [ ; grap the filename out of the received JSON data
$dataspace <yt-dlp $url $json> $cap ? <recv {filename: ?filename}> [
$config <require-service <daemon immutulator>>
; ask the real immutulator
$dataspace ? <immutulation $filename ?eris ?size ?mime> [
; answer the initial observation
$dataspace <immutulation-yt-dlp $url $eris $size $mime>
]
] ]
] ]
] ]
$config [ $config [
? <service-object <daemon video_immutulator> ?cap> [ ? <service-object <daemon immutulator> ?cap> [
$cap { $cap {
cachefile: "/srv/immutulator.pr" cachefile: "/srv/immutulator.pr"
dataspace: $dataspace dataspace: $dataspace
stores: [ "coap+tcp://192.168.160.1:5683" ] stores: [ "coap+tcp://[::1]:5683" ]
} }
] ]
] ]
@ -58,7 +71,7 @@ let ?ds = dataspace
And I use [syndump](https://git.syndicate-lang.org/ehmry/syndicate_utils#syndump) as a frontend: And I use [syndump](https://git.syndicate-lang.org/ehmry/syndicate_utils#syndump) as a frontend:
``` ```
$ SYNDICATE_STEP=$(mintsturdyref '"eris"' < /dev/null) syndump '<immutulation "https://www.youtube.com/watch?v=anwy2MPT5RE" ? ? ?>' $ SYNDICATE_STEP=$(mintsturdyref '"eris"' < /dev/null) syndump '<immutulation-yt-dlp "https://www.youtube.com/watch?v=anwy2MPT5RE" ? ? ?>'
# Output: # Output:
+ "urn:eris:B4A3BWB3NL3AG7JLQZJ3DEOH7G6FYG6LHFH2QTOV5VUEYTMK6NWTQEYVPP2JT2VN5YXXYLKKXR3MOF35DXFKTBOVTR55Z23JQO56D2S4MM" 6030153 video/webm + "urn:eris:B4A3BWB3NL3AG7JLQZJ3DEOH7G6FYG6LHFH2QTOV5VUEYTMK6NWTQEYVPP2JT2VN5YXXYLKKXR3MOF35DXFKTBOVTR55Z23JQO56D2S4MM" 6030153 video/webm

View File

@ -1,4 +1,4 @@
bin = @["video_immutulator"] bin = @["immutulator"]
license = "Unlicense" license = "Unlicense"
requires: "nim", "syndicate" requires: "nim", "syndicate"
srcDir = "src" srcDir = "src"

View File

@ -1,21 +1,10 @@
version 1. version 1.
embeddedType EntityRef.Cap . embeddedType EntityRef.Cap .
Immutulation = <immutulation @source string @erisCap string @length int @mimetype symbol> . Immutulation = <immutulation @filePath string @erisCap string @length int @mimetype symbol> .
BootArgs = { BootArgs = {
cachefile: string cachefile: string
dataspace: #!any dataspace: #!any
stores: [string ...] stores: [string ...]
} . } .
JSON =
/ @string string
/ @integer int
/ @double double
/ @boolean bool
/ @null =null
/ @array [JSON ...]
/ @object { symbol: JSON ...:... } .
YtDlp = <yt-dlp @url string @dump { symbol: JSON ...:... }> .

View File

@ -3,7 +3,7 @@ let
pkgs = pkgs =
import <nixpkgs> { overlays = (builtins.attrValues syndicate.overlays); }; import <nixpkgs> { overlays = (builtins.attrValues syndicate.overlays); };
in pkgs.nimPackages.buildNimPackage (finalAttrs: prevAttrs: { in pkgs.nimPackages.buildNimPackage (finalAttrs: prevAttrs: {
pname = "video_immutulator"; pname = "immutulator";
version = "unstable"; version = "unstable";
nativeBuildInputs = [ pkgs.pkg-config ]; nativeBuildInputs = [ pkgs.pkg-config ];
propagatedBuildInputs = [ pkgs.nimPackages.getdns ]; propagatedBuildInputs = [ pkgs.nimPackages.getdns ];

View File

@ -1,4 +1,4 @@
include_rules include_rules
: foreach ../*.prs |> !preserves_schema_nim |> {schema} : foreach ../*.prs |> !preserves_schema_nim |> {schema}
: video_immutulator.nim | $(SYNDICATE_PROTOCOL) {schema} |> !nim_bin |> {bin} : immutulator.nim | $(SYNDICATE_PROTOCOL) {schema} |> !nim_bin |> {bin}
: {bin} |> !assert_built |> : {bin} |> !assert_built |>

View File

@ -10,10 +10,10 @@ import ./protocol
type Observe = dataspace.Observe[Cap] type Observe = dataspace.Observe[Cap]
proc immutulate(turn: var Turn; ds: Cap; store: ErisStore; source: string, cacheStream: Stream) = proc immutulate(turn: var Turn; ds: Cap; store: ErisStore; filePath: string, cacheStream: Stream) =
onPublish(turn, ds, YtDlp ? {0: ?source, 1: grab()}) do (info: Preserve[void]): if fileExists(filePath):
stderr.writeLine "immutulate ", filePath
let let
filePath = info["filename".toSymbol].string
fileSize = filePath.getFileInfo.size fileSize = filePath.getFileInfo.size
mimeTypes = mimeTypeOf(filePath) mimeTypes = mimeTypeOf(filePath)
fileStream = openFileStream(filePath) fileStream = openFileStream(filePath)
@ -26,7 +26,7 @@ proc immutulate(turn: var Turn; ds: Cap; store: ErisStore; source: string, cache
ingest.cap.addCallback(turn) do (turn: var Turn; ec: ErisCap): ingest.cap.addCallback(turn) do (turn: var Turn; ec: ErisCap):
var rec = initRecord( var rec = initRecord(
"immutulation", "immutulation",
source.toPreserve(Cap), filePath.toPreserve(Cap),
($ec).toPreserve(Cap), ($ec).toPreserve(Cap),
fileSize.toPreserve(Cap), fileSize.toPreserve(Cap),
mimeType.toSymbol(Cap), mimeType.toSymbol(Cap),
@ -34,8 +34,10 @@ proc immutulate(turn: var Turn; ds: Cap; store: ErisStore; source: string, cache
discard publish(turn, ds, rec) discard publish(turn, ds, rec)
cacheStream.writeLine($rec) cacheStream.writeLine($rec)
cacheStream.flush() cacheStream.flush()
else:
stderr.writeLine "cannot immutulate file that does not exist: ", filePath
runActor("video_immutulator") do (root: Cap; turn: var Turn): runActor("immutulator") do (root: Cap; turn: var Turn):
connectStdio(root, turn) connectStdio(root, turn)
during(turn, root, ?BootArgs) do (cachefile: string, ds: Cap, stores: seq[string]): during(turn, root, ?BootArgs) do (cachefile: string, ds: Cap, stores: seq[string]):
let cacheStream = openFileStream(cachefile, fmAppend) let cacheStream = openFileStream(cachefile, fmAppend)
@ -50,8 +52,8 @@ runActor("video_immutulator") do (root: Cap; turn: var Turn):
store.add(c) store.add(c)
let pat = ?Observe(pattern: !Immutulation) ?? {0: grabLit()} let pat = ?Observe(pattern: !Immutulation) ?? {0: grabLit()}
during(turn, ds, pat) do (source: string): during(turn, ds, pat) do (filePath: string):
immutulate(turn, ds, store, source, cacheStream) immutulate(turn, ds, store, filePath, cacheStream)
do: do:
close(store) close(store)

View File

@ -1,57 +1,21 @@
import import
preserves, std/tables preserves
type type
YtDlp* {.acyclic, preservesRecord: "yt-dlp".} = ref object
`url`*: string
`dump`*: Table[Symbol, JSON]
BootArgs* {.preservesDictionary.} = object BootArgs* {.preservesDictionary.} = object
`cachefile`*: string `cachefile`*: string
`dataspace`* {.preservesEmbedded.}: Preserve[void] `dataspace`* {.preservesEmbedded.}: Preserve[void]
`stores`*: seq[string] `stores`*: seq[string]
JSONKind* {.pure.} = enum
`string`, `integer`, `double`, `boolean`, `null`, `array`, `object`
JSONString* = string
JSONInteger* = BiggestInt
JSONDouble* = float64
JSONBoolean* = bool
JSONArray* = seq[JSON]
JSONObject* = Table[Symbol, JSON]
`JSON`* {.acyclic, preservesOr.} = ref object
case orKind*: JSONKind
of JSONKind.`string`:
`string`*: JSONString
of JSONKind.`integer`:
`integer`*: JSONInteger
of JSONKind.`double`:
`double`*: JSONDouble
of JSONKind.`boolean`:
`boolean`*: JSONBoolean
of JSONKind.`null`:
`null`* {.preservesLiteral: "null".}: bool
of JSONKind.`array`:
`array`*: JSONArray
of JSONKind.`object`:
`object`*: JSONObject
Immutulation* {.preservesRecord: "immutulation".} = object Immutulation* {.preservesRecord: "immutulation".} = object
`source`*: string `filePath`*: string
`erisCap`*: string `erisCap`*: string
`length`*: BiggestInt `length`*: BiggestInt
`mimetype`*: Symbol `mimetype`*: Symbol
proc `$`*(x: YtDlp | BootArgs | JSON | Immutulation): string = proc `$`*(x: BootArgs | Immutulation): string =
`$`(toPreserve(x)) `$`(toPreserve(x))
proc encode*(x: YtDlp | BootArgs | JSON | Immutulation): seq[byte] = proc encode*(x: BootArgs | Immutulation): seq[byte] =
encode(toPreserve(x)) encode(toPreserve(x))