commit 8fd76d9a491c61a2a9e1b3f690b6f93e97758cb1 Author: Nat Quayle Nelson Date: Mon Jun 7 12:36:22 2021 -0600 Refactor travis testing diff --git a/haxelib.json b/haxelib.json new file mode 100644 index 0000000..82b7351 --- /dev/null +++ b/haxelib.json @@ -0,0 +1,15 @@ +{ + "name": "nat-archive-tool", + "url": "https://github.com/hissvn/kisslang", + "license": "LGPL", + "tags": ["cross"], + "description": "", + "version": "0.0.0", + "releasenote": "It isn't safe to use this library yet.", + "contributors": ["NQNStudios"], + "classPath": "src/", + "dependencies": { + "kiss": "", + "tink_json": "" + } +} \ No newline at end of file diff --git a/ideas.txt b/ideas.txt new file mode 100644 index 0000000..05136d5 --- /dev/null +++ b/ideas.txt @@ -0,0 +1,2 @@ +program that helps you cobble together journal entries retroactively using your texts and message history from that day. and calendar etc +music player that youtubeDLs the songs you like, and will play songs by artists you like diff --git a/src/nat/Archive.hx b/src/nat/Archive.hx new file mode 100644 index 0000000..dcb2f96 --- /dev/null +++ b/src/nat/Archive.hx @@ -0,0 +1,12 @@ +package nat; + +import sys.FileSystem; +import kiss.Prelude; +import sys.io.File; +import tink.Json; +import uuid.Uuid; + +using haxe.io.Path; + +@:build(kiss.Kiss.build()) +class Archive {} diff --git a/src/nat/Archive.kiss b/src/nat/Archive.kiss new file mode 100644 index 0000000..4fd729b --- /dev/null +++ b/src/nat/Archive.kiss @@ -0,0 +1,42 @@ +(defnew [&prop :String archiveDir] + + [:Array systems + [] + :Map templates + (new Map) + :Map entries + (let [entryFiles (FileSystem.readDirectory (Path.join [archiveDir "entries"]))] + (for file entryFiles =>(file.withoutExtension) ~(the Entry (Json.parse (File.getContent (Path.join [archiveDir "entries" file]))))))]) + +(defmethod addSystem [:System system] + // Assign entries to the Systems that care about them + (doFor =>id entry entries + (system.checkEntryInOrOut this entry)) + (systems.push system)) + +(defmethod addTemplate [name template] + (dictSet templates name template)) + +(defmethod :Entry createEntry [template] + (let [e (_newEntry)] + (.prepareEntry (dictGet templates template) e) + (doFor system systems + (system.checkEntryInOrOut this e)) + e)) + +(defmethod saveEntry [:Entry e] + (File.saveContent + (Path.join [archiveDir "entries" (e.id.withExtension "json")]) + (Json.stringify e)) + + // TODO save its components? but it's not obvious how, because it only knows the string keys of them. + // Better yet, retrieving components with mutable access should be done through a + // (withComponent...) macro that serializes the component after the block is done. + // + ) + +(defun :Entry _newEntry [] + (object + id (Uuid.v4) + components (new Map) + files [])) \ No newline at end of file diff --git a/src/nat/BoolExpInterp.hx b/src/nat/BoolExpInterp.hx new file mode 100644 index 0000000..41f835d --- /dev/null +++ b/src/nat/BoolExpInterp.hx @@ -0,0 +1,20 @@ +package nat; + +import kiss.KissInterp; +import hscript.Parser; +import kiss.Prelude; + +@:build(kiss.Kiss.build()) +class BoolExpInterp extends KissInterp { + public function new() { + super(); + } + + override function resolve(id:String):Dynamic { + return try { + super.resolve(id); + } catch (e:Dynamic) { + false; + } + } +} diff --git a/src/nat/BoolExpInterp.kiss b/src/nat/BoolExpInterp.kiss new file mode 100644 index 0000000..df53363 --- /dev/null +++ b/src/nat/BoolExpInterp.kiss @@ -0,0 +1,9 @@ +(defun eval [:String expStr :Array activeConditions] + (let [hscriptExp + (.parseString (new Parser) + (Prelude.convertToHScript expStr)) + interp + (new BoolExpInterp)] + (doFor condition activeConditions + (interp.variables.set condition true)) + ?(interp.execute hscriptExp))) \ No newline at end of file diff --git a/src/nat/Entry.hx b/src/nat/Entry.hx new file mode 100644 index 0000000..c7f1ccf --- /dev/null +++ b/src/nat/Entry.hx @@ -0,0 +1,7 @@ +package nat; + +typedef Entry = { + id:String, + components:Map, + files:Array +}; diff --git a/src/nat/Lib.hx b/src/nat/Lib.hx new file mode 100644 index 0000000..0832f1a --- /dev/null +++ b/src/nat/Lib.hx @@ -0,0 +1,11 @@ +package nat; + +import kiss.Prelude; +import sys.io.File; +import tink.Json; +import uuid.Uuid; + +using haxe.io.Path; + +@:build(kiss.Kiss.build()) +class Lib {} diff --git a/src/nat/Lib.kiss b/src/nat/Lib.kiss new file mode 100644 index 0000000..ee6cb1a --- /dev/null +++ b/src/nat/Lib.kiss @@ -0,0 +1,20 @@ +// Lib is its own class because, while it would make sense to group its functions and macros in Archive.kiss, +// other files would not be able to (load "Archive.kiss") for the macro definitions without taking on Archive's constructor. + +(defmacro hasComponent [e componentType] + `(.exists .components ,e ,(symbolName componentType))) + +// TODO add to the documentation a hint that macros should use fully qualified paths so macro caller classes don't need to import everything +(defmacro getComponent [archive e componentType] + `(the nat.components ,componentType + (tink.Json.parse + (sys.io.File.getContent + (haxe.io.Path.join [.archiveDir (the nat.Archive ,archive) "components" (+ (dictGet (the Map .components ,e) ,(symbolName componentType)) ".json")]))))) + +(defun tagList [archive e] + (let [t + (getComponent archive e Tags)] + (collect (t.keys)))) + +(defun tagsMatch [archive e tagsBoolExp] + (BoolExpInterp.eval tagsBoolExp (tagList archive e))) \ No newline at end of file diff --git a/src/nat/System.hx b/src/nat/System.hx new file mode 100644 index 0000000..657d74f --- /dev/null +++ b/src/nat/System.hx @@ -0,0 +1,9 @@ +package nat; + +import kiss.Prelude; + +typedef EntryChecker = (Archive, Entry) -> Bool; +typedef EntryProcessor = (Archive, Entry) -> Void; + +@:build(kiss.Kiss.build()) +class System {} diff --git a/src/nat/System.kiss b/src/nat/System.kiss new file mode 100644 index 0000000..2714df9 --- /dev/null +++ b/src/nat/System.kiss @@ -0,0 +1,13 @@ +(defprop :Map entries (new Map)) + +(defmethod :Void process [:Archive archive] + (doFor e (entries.iterator) (processEntry archive e))) + +(defnew [&prop :EntryChecker canProcessEntry + &prop :EntryProcessor processEntry] + []) + +(defmethod :Void checkEntryInOrOut [:Archive archive :Entry e] + (if (canProcessEntry archive e) + (dictSet entries e.id e) + (entries.remove e.id))) diff --git a/src/nat/Template.hx b/src/nat/Template.hx new file mode 100644 index 0000000..d4a3065 --- /dev/null +++ b/src/nat/Template.hx @@ -0,0 +1,5 @@ +package nat; + +interface Template { + function prepareEntry(e:Entry):Void; +} diff --git a/src/nat/components/Dates.hx b/src/nat/components/Dates.hx new file mode 100644 index 0000000..f41ae90 --- /dev/null +++ b/src/nat/components/Dates.hx @@ -0,0 +1,3 @@ +package nat.components; + +typedef Tags = Map; diff --git a/src/nat/components/StringComponents.hx b/src/nat/components/StringComponents.hx new file mode 100644 index 0000000..838abe4 --- /dev/null +++ b/src/nat/components/StringComponents.hx @@ -0,0 +1,4 @@ +package nat.components; + +typedef Name = String; +typedef Author = String; diff --git a/src/nat/components/Tags.hx b/src/nat/components/Tags.hx new file mode 100644 index 0000000..8d2d265 --- /dev/null +++ b/src/nat/components/Tags.hx @@ -0,0 +1,3 @@ +package nat.components; + +typedef Tags = Map; diff --git a/src/nat/systems/TagSystem.hx b/src/nat/systems/TagSystem.hx new file mode 100644 index 0000000..1172233 --- /dev/null +++ b/src/nat/systems/TagSystem.hx @@ -0,0 +1,6 @@ +package nat.systems; + +import kiss.Prelude; + +@:build(kiss.Kiss.build()) +class TagSystem extends System {} diff --git a/src/nat/systems/TagSystem.kiss b/src/nat/systems/TagSystem.kiss new file mode 100644 index 0000000..5d56920 --- /dev/null +++ b/src/nat/systems/TagSystem.kiss @@ -0,0 +1,9 @@ +(load "../Lib.kiss") + +// TODO make a &super annotation that passes an argument to the super constructor +(defnew [&prop :String tagFilterString + &prop :EntryProcessor processor] + [] + (super + (lambda [:Archive archive :Entry e] (tagsMatch archive e tagFilterString)) + processor)) \ No newline at end of file diff --git a/src/test/TestMain.hx b/src/test/TestMain.hx new file mode 100644 index 0000000..b6abeb5 --- /dev/null +++ b/src/test/TestMain.hx @@ -0,0 +1,11 @@ +package test; + +import kiss.Kiss; +import kiss.Prelude; +import nat.BoolExpInterp; +import nat.Archive; +import nat.Lib; +import nat.components.*; + +@:build(kiss.Kiss.build()) +class TestMain {} diff --git a/src/test/TestMain.kiss b/src/test/TestMain.kiss new file mode 100644 index 0000000..93ae866 --- /dev/null +++ b/src/test/TestMain.kiss @@ -0,0 +1,28 @@ +// TODO external programs need to be able to find and (load) this path to get the macros: +// ^ That should be solved by allowing an optional first argument to load that is a symbol +// of a library name that can be used to resolve the source dir in the user's Haxelib maybe? +(load "../nat/Lib.kiss") + + +(defun :Void main [] + (assert (BoolExpInterp.eval "true" [])) + (assert !(BoolExpInterp.eval "false" [])) + (assert !(BoolExpInterp.eval "flag" [])) + (assert (BoolExpInterp.eval "flag" ["flag"])) + (assert !(BoolExpInterp.eval "(and flag false)" ["flag"])) + (assert (BoolExpInterp.eval "(or flag otherFlag)" ["otherFlag"])) + //trace(error); + (let [archive + (new Archive "src/test/example-archive") + song1 + (dictGet archive.entries "song1") + song2 + (dictGet archive.entries "song2")] + + (assert (hasComponent song1 Tags)) + (assert (hasComponent song2 Tags)) + (assert (tagsMatch archive song1 "(and song western)")) + (assert !(tagsMatch archive song1 "(and song religious)")) + (assert (tagsMatch archive song2 "(and song religious)")) + (assert !(tagsMatch archive song2 "(and song western)")) + )) \ No newline at end of file diff --git a/src/test/example-archive/components/author1.json b/src/test/example-archive/components/author1.json new file mode 100644 index 0000000..500b26f --- /dev/null +++ b/src/test/example-archive/components/author1.json @@ -0,0 +1 @@ +"Rafael Krux" \ No newline at end of file diff --git a/src/test/example-archive/components/author2.json b/src/test/example-archive/components/author2.json new file mode 100644 index 0000000..1b4c08b --- /dev/null +++ b/src/test/example-archive/components/author2.json @@ -0,0 +1 @@ +"Kevin MacLeod" \ No newline at end of file diff --git a/src/test/example-archive/components/name1.json b/src/test/example-archive/components/name1.json new file mode 100644 index 0000000..10700c0 --- /dev/null +++ b/src/test/example-archive/components/name1.json @@ -0,0 +1 @@ +"Adventure" \ No newline at end of file diff --git a/src/test/example-archive/components/name2.json b/src/test/example-archive/components/name2.json new file mode 100644 index 0000000..aa59682 --- /dev/null +++ b/src/test/example-archive/components/name2.json @@ -0,0 +1 @@ +"Ancient Rite" \ No newline at end of file diff --git a/src/test/example-archive/components/tags1.json b/src/test/example-archive/components/tags1.json new file mode 100644 index 0000000..ed3e424 --- /dev/null +++ b/src/test/example-archive/components/tags1.json @@ -0,0 +1,4 @@ +[ + ["song", 1], + ["western", 1] +] \ No newline at end of file diff --git a/src/test/example-archive/components/tags2.json b/src/test/example-archive/components/tags2.json new file mode 100644 index 0000000..9747a3d --- /dev/null +++ b/src/test/example-archive/components/tags2.json @@ -0,0 +1,4 @@ +[ + ["song", 1], + ["religious", 1] +] \ No newline at end of file diff --git a/src/test/example-archive/entries/song1.json b/src/test/example-archive/entries/song1.json new file mode 100644 index 0000000..d08dc0a --- /dev/null +++ b/src/test/example-archive/entries/song1.json @@ -0,0 +1,11 @@ +{ + "id": "song1", + "components": [ + ["Name", "name1"], + ["Author", "author1"], + ["Tags", "tags1"] + ], + "files": [ + "Adventure.mp3" + ] +} \ No newline at end of file diff --git a/src/test/example-archive/entries/song2.json b/src/test/example-archive/entries/song2.json new file mode 100644 index 0000000..aa8e6b6 --- /dev/null +++ b/src/test/example-archive/entries/song2.json @@ -0,0 +1,11 @@ +{ + "id": "song2", + "components": [ + ["Name", "name2"], + ["Author", "author2"], + ["Tags", "tags2"] + ], + "files": [ + "Ancient Rite.mp3" + ] +} \ No newline at end of file diff --git a/src/test/example-archive/files/Adventure.mp3 b/src/test/example-archive/files/Adventure.mp3 new file mode 100644 index 0000000..e9b3c1b Binary files /dev/null and b/src/test/example-archive/files/Adventure.mp3 differ diff --git a/src/test/example-archive/files/Ancient Rite.mp3 b/src/test/example-archive/files/Ancient Rite.mp3 new file mode 100644 index 0000000..63d25e4 Binary files /dev/null and b/src/test/example-archive/files/Ancient Rite.mp3 differ diff --git a/test.hxml b/test.hxml new file mode 100644 index 0000000..a0d212f --- /dev/null +++ b/test.hxml @@ -0,0 +1,6 @@ +-D test +-lib kiss +-lib nat-archive-tool +-cp test +--main test.TestMain +--interp \ No newline at end of file diff --git a/test.sh b/test.sh new file mode 100644 index 0000000..627c3a5 --- /dev/null +++ b/test.sh @@ -0,0 +1,4 @@ +#! /bin/bash + +haxelib dev nat-archive-tool . +haxe test.hxml \ No newline at end of file diff --git a/tools/nap-music/build.hxml b/tools/nap-music/build.hxml new file mode 100644 index 0000000..bfdff6e --- /dev/null +++ b/tools/nap-music/build.hxml @@ -0,0 +1,5 @@ +-lib kiss +-lib nat-archive-tool +-cp src +--main Main +--interp \ No newline at end of file diff --git a/tools/nap-music/src/Main.hx b/tools/nap-music/src/Main.hx new file mode 100644 index 0000000..3c94bff --- /dev/null +++ b/tools/nap-music/src/Main.hx @@ -0,0 +1,8 @@ +package; + +import kiss.Kiss; +import kiss.Prelude; +import nat.Archive; + +@:build(kiss.Kiss.build()) +class Main {} diff --git a/tools/nap-music/src/Main.kiss b/tools/nap-music/src/Main.kiss new file mode 100644 index 0000000..24b3c98 --- /dev/null +++ b/tools/nap-music/src/Main.kiss @@ -0,0 +1,2 @@ +(defun :Void main [] + (print "Hello world!")) \ No newline at end of file