From 5b17a75fab8275aebb22de6d6bfcd3e52f3f000a Mon Sep 17 00:00:00 2001 From: Taran Nathan Date: Wed, 10 Jun 2026 23:40:08 -0400 Subject: [PATCH] wowza --- .github/workflows/test.yml | 23 ++++++++++ .gitignore | 4 ++ README.md | 24 ++++++++++ files/focus.sh | 19 ++++++++ files/test.txt | 3 ++ gleam.toml | 30 +++++++++++++ manifest.toml | 46 +++++++++++++++++++ src/preview.gleam | 39 ++++++++++++++++ src/router.gleam | 90 +++++++++++++++++++++++++++++++++++++ static/form.html | 91 ++++++++++++++++++++++++++++++++++++++ static/styles.css | 58 ++++++++++++++++++++++++ test/preview_test.gleam | 18 ++++++++ 12 files changed, 445 insertions(+) create mode 100644 .github/workflows/test.yml create mode 100644 .gitignore create mode 100644 README.md create mode 100644 files/focus.sh create mode 100644 files/test.txt create mode 100644 gleam.toml create mode 100644 manifest.toml create mode 100644 src/preview.gleam create mode 100644 src/router.gleam create mode 100644 static/form.html create mode 100644 static/styles.css create mode 100644 test/preview_test.gleam diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..eb4a679 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,23 @@ +name: test + +on: + push: + branches: + - master + - main + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: erlef/setup-beam@v1 + with: + otp-version: "28" + gleam-version: "1.16.0" + rebar3-version: "3" + # elixir-version: "1" + - run: gleam deps download + - run: gleam test + - run: gleam format --check src test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..599be4e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.beam +*.ez +/build +erl_crash.dump diff --git a/README.md b/README.md new file mode 100644 index 0000000..6be9ddc --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# preview + +[![Package Version](https://img.shields.io/hexpm/v/preview)](https://hex.pm/packages/preview) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/preview/) + +```sh +gleam add preview@1 +``` +```gleam +import preview + +pub fn main() -> Nil { + // TODO: An example of the project in use +} +``` + +Further documentation can be found at . + +## Development + +```sh +gleam run # Run the project +gleam test # Run the tests +``` diff --git a/files/focus.sh b/files/focus.sh new file mode 100644 index 0000000..19de0b8 --- /dev/null +++ b/files/focus.sh @@ -0,0 +1,19 @@ +regex='(YouTube|: r\/|Reddit|Lunar)' + +while true; do + # get window name (trim trailing newline) + name="$(kdotool getactivewindow getwindowname 2>/dev/null | tr -d '\r\n')" + + if [[ -z "$name" ]]; then + sleep 1 + continue + fi + + if [[ "$name" =~ $regex ]]; then + echo "Match: $name" + notify-send "naughty boy" + # exit 0 + fi + + sleep 1 +done diff --git a/files/test.txt b/files/test.txt new file mode 100644 index 0000000..3fea1b8 --- /dev/null +++ b/files/test.txt @@ -0,0 +1,3 @@ +hello! + +bazinga! diff --git a/gleam.toml b/gleam.toml new file mode 100644 index 0000000..acf4aa9 --- /dev/null +++ b/gleam.toml @@ -0,0 +1,30 @@ +name = "preview" +version = "1.0.0" + +# Fill out these fields if you intend to generate HTML documentation or publish +# your project to the Hex package manager. +# +# description = "" +# licences = ["Apache-2.0"] +# repository = { type = "github", user = "", repo = "" } +# links = [{ title = "Website", href = "" }] +# +# For a full reference of all the available options, you can have a look at +# https://gleam.run/writing-gleam/gleam-toml/. + +[dependencies] +gleam_stdlib = ">= 1.0.0 and < 2.0.0" +argv = ">= 1.1.0 and < 2.0.0" +gleam_erlang = ">= 1.3.0 and < 2.0.0" +gleam_http = ">= 4.3.0 and < 5.0.0" +logging = ">= 1.5.0 and < 2.0.0" +wisp = ">= 2.2.2 and < 3.0.0" +gleam_otp = ">= 1.2.0 and < 2.0.0" +gleam_json = ">= 3.1.0 and < 4.0.0" +gleam_time = ">= 1.8.0 and < 2.0.0" +simplifile = ">= 2.4.0 and < 3.0.0" +mist = ">= 6.0.3 and < 7.0.0" + +[dev_dependencies] +gleeunit = ">= 1.0.0 and < 2.0.0" +gleescript = ">= 1.5.2 and < 2.0.0" diff --git a/manifest.toml b/manifest.toml new file mode 100644 index 0000000..717b1ae --- /dev/null +++ b/manifest.toml @@ -0,0 +1,46 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "argv", version = "1.1.0", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "3277D100448BDB4A29B6D58C0F36F631CBC349E8BDD09766C6309DF202831140" }, + { name = "directories", version = "1.2.0", build_tools = ["gleam"], requirements = ["envoy", "gleam_stdlib", "platform", "simplifile"], otp_app = "directories", source = "hex", outer_checksum = "D13090CFCDF6759B87217E8DDD73A75903A700148A82C1D33799F333E249BF9E" }, + { name = "envoy", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "envoy", source = "hex", outer_checksum = "9C6FBB6BFA02A52798BEEC5977A738CAD6E4A057F4B67FD0C8061AD2502C191A" }, + { name = "exception", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "329D269D5C2A314F7364BD2711372B6F2C58FA6F39981572E5CA68624D291F8C" }, + { name = "filepath", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "B06A9AF0BF10E51401D64B98E4B627F1D2E48C154967DA7AF4D0914780A6D40A" }, + { name = "gleam_crypto", version = "1.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_crypto", source = "hex", outer_checksum = "2DE9E4EF53CF6FEE049D4F765731F7178F7A11AEFAE00EEE63BF7536B354AD3F" }, + { name = "gleam_erlang", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "1124AD3AA21143E5AF0FC5CF3D9529F6DB8CA03E43A55711B60B6B7B3874375C" }, + { name = "gleam_http", version = "4.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "82EA6A717C842456188C190AFB372665EA56CE13D8559BF3B1DD9E40F619EE0C" }, + { name = "gleam_json", version = "3.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "44FDAA8847BE8FC48CA7A1C089706BD54BADCC4C45B237A992EDDF9F2CDB2836" }, + { name = "gleam_otp", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "BA6A294E295E428EC1562DC1C11EA7530DCB981E8359134BEABC8493B7B2258E" }, + { name = "gleam_stdlib", version = "1.0.3", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "1F543AFBA5D33DA493E6087F4E4C4F20D899411343512686C98A8ABB2963CF22" }, + { name = "gleam_time", version = "1.8.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_time", source = "hex", outer_checksum = "533D8723774D61AD4998324F5DD1DABDCDBFABAFB9E87CB5D03C6955448FC97D" }, + { name = "gleescript", version = "1.5.2", build_tools = ["gleam"], requirements = ["argv", "filepath", "gleam_erlang", "gleam_stdlib", "simplifile", "snag", "tom"], otp_app = "gleescript", source = "hex", outer_checksum = "27AC58481742ED29D9B37C506F78958A8AD798750A79ED08C8F8AFBA8F23563B" }, + { name = "gleeunit", version = "1.11.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "EC31ABA74256AEA531EDF8169931D775BBB384FED0A8A1BDC4DD9354E3E21826" }, + { name = "glisten", version = "9.0.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib", "logging"], otp_app = "glisten", source = "hex", outer_checksum = "7795AA50830656F3A0316A6B26595F893C83272DA901B3405E31339CAA31A10B" }, + { name = "gramps", version = "6.0.1", build_tools = ["gleam"], requirements = ["gleam_crypto", "gleam_erlang", "gleam_http", "gleam_stdlib"], otp_app = "gramps", source = "hex", outer_checksum = "D55636072DEE173F6586A5679D3C02EC7A0DE3F8646B78C351B72908FF223DF7" }, + { name = "houdini", version = "1.2.1", build_tools = ["gleam"], requirements = [], otp_app = "houdini", source = "hex", outer_checksum = "6F8AC2F12974567FB744BEA66AC93CEB76AAEA19AD28564623F76CDA9BC26A85" }, + { name = "hpack_erl", version = "0.3.0", build_tools = ["rebar3"], requirements = [], otp_app = "hpack", source = "hex", outer_checksum = "D6137D7079169D8C485C6962DFE261AF5B9EF60FBC557344511C1E65E3D95FB0" }, + { name = "logging", version = "1.5.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "logging", source = "hex", outer_checksum = "BC5F18CE5DD9686100229FE5409BDC3DD5C46D5A7DF2F804AD2D8F0DD6C5060E" }, + { name = "marceau", version = "1.3.0", build_tools = ["gleam"], requirements = [], otp_app = "marceau", source = "hex", outer_checksum = "2D1C27504BEF45005F5DFB18591F8610FB4BFA91744878210BDC464412EC44E9" }, + { name = "mist", version = "6.0.3", build_tools = ["gleam"], requirements = ["exception", "gleam_erlang", "gleam_http", "gleam_otp", "gleam_stdlib", "glisten", "gramps", "hpack_erl", "logging"], otp_app = "mist", source = "hex", outer_checksum = "1B07F321D5FA0CB162D81496F2DE96AEB6EF8980F4F38230A4CC3F849497E020" }, + { name = "platform", version = "1.0.0", build_tools = ["gleam"], requirements = [], otp_app = "platform", source = "hex", outer_checksum = "8339420A95AD89AAC0F82F4C3DB8DD401041742D6C3F46132A8739F6AEB75391" }, + { name = "simplifile", version = "2.4.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "7C18AFA4FED0B4CE1FA5B0B4BAC1FA1744427054EA993565F6F3F82E5453170D" }, + { name = "snag", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "snag", source = "hex", outer_checksum = "274F41D6C3ECF99F7686FDCE54183333E41D2C1CA5A3A673F9A8B2C7A4401077" }, + { name = "tom", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_time"], otp_app = "tom", source = "hex", outer_checksum = "DCF04CB7AB35D58CFC598C66EA2E1816D160759802C89B2BA6238780D59BC256" }, + { name = "wisp", version = "2.2.2", build_tools = ["gleam"], requirements = ["directories", "exception", "filepath", "gleam_crypto", "gleam_erlang", "gleam_http", "gleam_json", "gleam_stdlib", "houdini", "logging", "marceau", "mist", "simplifile"], otp_app = "wisp", source = "hex", outer_checksum = "5FF5F1E288C3437252ABB93D8F9CF42FF652CE7AD54480CFE736038DC09C4F22" }, +] + +[requirements] +argv = { version = ">= 1.1.0 and < 2.0.0" } +gleam_erlang = { version = ">= 1.3.0 and < 2.0.0" } +gleam_http = { version = ">= 4.3.0 and < 5.0.0" } +gleam_json = { version = ">= 3.1.0 and < 4.0.0" } +gleam_otp = { version = ">= 1.2.0 and < 2.0.0" } +gleam_stdlib = { version = ">= 1.0.0 and < 2.0.0" } +gleam_time = { version = ">= 1.8.0 and < 2.0.0" } +gleescript = { version = ">= 1.5.2 and < 2.0.0" } +gleeunit = { version = ">= 1.0.0 and < 2.0.0" } +logging = { version = ">= 1.5.0 and < 2.0.0" } +mist = { version = ">= 6.0.3 and < 7.0.0" } +simplifile = { version = ">= 2.4.0 and < 3.0.0" } +wisp = { version = ">= 2.2.2 and < 3.0.0" } diff --git a/src/preview.gleam b/src/preview.gleam new file mode 100644 index 0000000..947a17c --- /dev/null +++ b/src/preview.gleam @@ -0,0 +1,39 @@ +import argv +import gleam/erlang/process +import gleam/io +import mist +import router +import wisp +import wisp/wisp_mist + +pub fn main() -> Nil { + let args: List(String) = argv.load().arguments + case args { + ["greet", name] -> io.println("hello " <> name <> "!") + ["web", file_path] -> web(file_path) + _ -> io.println("bad args") + } + + // wisp.configure_logger() + + Nil +} + +pub fn wassup() -> Int { + 42 +} + +fn web(file_path: String) -> Nil { + wisp.configure_logger() + + let secret_key_base = wisp.random_string(64) + + let assert Ok(_) = + router.handle_request(_, file_path) + |> wisp_mist.handler(secret_key_base) + |> mist.new + |> mist.port(8000) + |> mist.start + + process.sleep_forever() +} diff --git a/src/router.gleam b/src/router.gleam new file mode 100644 index 0000000..c32d12b --- /dev/null +++ b/src/router.gleam @@ -0,0 +1,90 @@ +import gleam/bool +import gleam/list +import gleam/result +import simplifile +import wisp + +pub fn handle_request(req: wisp.Request, file_path: String) -> wisp.Response { + use req <- middleware(req) + // use <- wisp.serve_static(req, "/files", file_path) + + case req.path { + "/index.html" -> main_page(req) + "/" -> main_page(req) + "/styles.css" -> { + use <- wisp.serve_static(req, "/styles.css", "./static/styles.css") + wisp.ok() + } + "/new/" <> _path -> upload(req) + "/files/" <> path -> files(req, "/" <> path, file_path) + _ -> wisp.not_found() + } +} + +fn files(req: wisp.Request, path: String, file_path) -> wisp.Response { + //TODO case req.headers smth smth + use <- wisp.serve_static(req, "/files", file_path) + wisp.ok() +} + +const password = "greg" + +pub fn upload(req: wisp.Request) -> wisp.Response { + use form <- wisp.require_form(req) + + //early return if incorrect password + use <- bool.guard( + when: result.unwrap(list.key_find(form.values, "password"), "") != password, + return: wisp.response(401), + ) + + wisp.log_debug(result.unwrap(list.key_find(form.values, "password"), "")) + + case form.files { + [#("file", wisp.UploadedFile(file_name:, path: temp_path)), ..] -> { + let destination = + "./files/" + <> result.unwrap(list.key_find(form.values, "filename"), file_name) + + let result = { + use _ <- result.try(simplifile.create_directory_all("./files")) + + simplifile.copy(temp_path, destination) + } + + case result { + Ok(_) -> + wisp.response(200) + |> wisp.set_body(wisp.Text("Upload successful")) + + Error(_) -> wisp.internal_server_error() + } + } + + _ -> wisp.bad_request("idk bro") + } +} + +fn main_page(req: wisp.Request) -> wisp.Response { + wisp.html_response( + result.unwrap(simplifile.read("./static/form.html"), ""), + 200, + ) +} + +fn middleware( + req: wisp.Request, + handler: fn(wisp.Request) -> wisp.Response, +) -> wisp.Response { + let req = wisp.method_override(req) + + use <- wisp.log_request(req) + + use <- wisp.rescue_crashes + + use req <- wisp.handle_head(req) + + use req <- wisp.csrf_known_header_protection(req) + + handler(req) +} diff --git a/static/form.html b/static/form.html new file mode 100644 index 0000000..128f31a --- /dev/null +++ b/static/form.html @@ -0,0 +1,91 @@ + + + + + + File Upload + + + +

File Upload

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ +

+ + + + diff --git a/static/styles.css b/static/styles.css new file mode 100644 index 0000000..25df8fe --- /dev/null +++ b/static/styles.css @@ -0,0 +1,58 @@ +body { + font-family: sans-serif; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + margin: 0; +} + +h1 { + margin-bottom: 20px; +} + +#upload-form { + display: flex; + flex-direction: column; + align-items: center; +} + +input { + padding: 10px; + margin-bottom: 10px; + width: 300px; + border: 1px solid #ccc; + border-radius: 4px; +} + +button { + padding: 10px 20px; + border: none; + background-color: #007bff; + color: white; + border-radius: 4px; + cursor: pointer; +} + +button:hover { + background-color: #0056b3; +} + +#upload-form { + width: 400px; +} + +#upload-form>div { + width: 100%; +} + +#upload-form input { + width: 100%; + box-sizing: border-box; +} + +#response-message { + margin-top: 20px; + font-size: 1.1em; +} \ No newline at end of file diff --git a/test/preview_test.gleam b/test/preview_test.gleam new file mode 100644 index 0000000..456d957 --- /dev/null +++ b/test/preview_test.gleam @@ -0,0 +1,18 @@ +import gleeunit +import preview + +pub fn main() -> Nil { + gleeunit.main() +} + +// gleeunit test functions end in `_test` +pub fn hello_world_test() { + let name = "Joe" + let greeting = "Hello, " <> name <> "!" + + assert greeting == "Hello, Joe!" +} + +pub fn wassup_test() { + assert preview.wassup() == 42 +} -- 2.47.3