diff --git a/docs/CC0 b/docs/CC0 new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/docs/CC0 @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 0000000..271c14d --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1,325 @@ +# changelog + +## surplus v2024.0.0 + +(unreleased) + +!!! information + this is a tentative release. surplus is currently versioned as `2024.0.0-beta`, as its + behaviour is not stabilized + +!!! warning + this is an api-breaking release. see 'the great api break'. + command-line usage of surplus has not changed + +### what's new + +- added flag `--show-user-agent`, printing the fingerprinted user agent string and exiting + +### what's changed + +- `default_geocoder()` and `default_reverser()` have been deprecated since v2.1.0 and are now + removed. use the `SurplusDefaultGeocoding` class instead +- `SurplusException` is now `SurplusError` + +### the great api break + +TODO + +### thanks! + +- [vlshields](https://github.com/vlshields/) for their support with a drink! + +full changelog: + +## surplus on wheels v2 + +(released on the 1st of July 2024 on tag `v2.2024.25+spow`) + +### changes + +- you can now customize command invocations with `SURPLUS_CMD` and `LOCATION_CMD` environment variables +- surplus on wheels will purge logs when setting the `SPOW_PRIVATE` environment flag + +### thanks! + +- [vlshields](https://github.com/vlshields/) for their support with a drink! + +--- + +## surplus on wheels: WhatsApp Bridge v2.2024.25 + +(released on the 17th of June 2024 on tag `v2.2024.25+spow-whatsapp-bridge`) + +!!! note + from henceforth, the WhatsApp Bridge is now versioned with a modified calendar versioning scheme + of `MAJOR.YEAR.ISOWEEK`, where the `MAJOR` version segment will be bumped with codebase changes, + whereas the `YEAR` and `ISOWEEK` segments will represent the time of which the release was + built at + +### changes + +- updated dependencies to latest versions +- added `pair-phone` and `reconnect` subcommands +- TODO added optional helper script to auto-update to newer versions via a user-made daily cron job + +### thanks! + +- [vlshields](https://github.com/vlshields/) for their support with a drink! + +--- + +## surplus on wheels: Telegram Bridge v2.2024.25 + +(released on the 17th of June 2024 on tag `v2.2024.25+spow-telegram-bridge`) + +!!! note + from henceforth, the Telegram Bridge will automatically release a new version once a week if + there are updates to its dependencies + + as such, the bridge is now versioned with a modified calendar versioning scheme of + `MAJOR.YEAR.ISOWEEK`, where the `MAJOR` version segment will be bumped with codebase changes, + whereas the `YEAR` and `ISOWEEK` segments will represent the time of which the release was + built at + +### changes + +- updated dependencies to latest versions +- added `logout` subcommand +- TODO added optional helper script to auto-update to newer versions via a user-made daily cron job + +### thanks! + +- [vlshields](https://github.com/vlshields/) for their support with a drink! + +--- + +## surplus on wheels v1 + +initial release on the 9th of November 2023 + +--- + +## surplus on wheels: WhatsApp Bridge v1 + +initial release on the 7th of November 2023 + +--- + +## surplus on wheels: Telegram Bridge v1 + +initial release on the 7th of November 2023 + +--- + +## surplus v2.2.0 + +(released on the 14th of October 2023) + +!!! warning + constants are changed in this update! + +fixed a bug installing surplus on Python 3.12 and italian sharetext fixes + +### what's new + +- special key arrangements for malaysia +- support for termux-location json input + +### what's fixed + +- fixed typing-extensions as an unwritten dependency + this also fixes a bug in not being able to run surplus in Python 3.12 +- fixed italian key arrangements [#34](https://github.com/markjoshwel/surplus/pull/34) + +### what's changed + +- **`SHAREABLE*` constants are now dictionaries, see api docs for more information** + + + +--- + +## surplus v2.1.1 + +(released on the 19th of September 2023) + +fix roads not coming first in Italian addresses (#31) + +- documentation enhancements + - remove self in `SurplusReverserProtocol` conforming signature + - fix mismatching carets and add info on `split_iso3166_2` +- alternative line 3 arrangement for IT/Italy in [#31](https://github.com/markjoshwel/surplus/pull/31) + + + +--- + +## surplus v2.1.0 + +(released on the 6th of September 2023) + +!!! warning + there are backwards-compatible api changes in this release. + +type-to-type location representation conversions and quality of life changes/fixes + +- **`default_geocoder()` and `default_reverser()` functions have been deprecated in favour of the + new [`SurplusDefaultGeocoding` class](https://github.com/markjoshwel/surplus/tree/main#class-surplusdefaultgeocoding)** +- add reading from stdin when query is "-" in [#23](https://github.com/markjoshwel/surplus/pull/23) +- type to type conversion in [#24](https://github.com/markjoshwel/surplus/pull/24) +- fix local codes not being recognised if split with comma in [#29](https://github.com/markjoshwel/surplus/pull/29) +- more verbose -v/--version information in [#21](https://github.com/markjoshwel/surplus/pull/21) + + + +--- + +## surplus v2.0.1 + +(released on the 5th of September 2023) + +- expose surplus.Result in `__init__.py` by in [#28](https://github.com/markjoshwel/surplus/pull/28) + + + +--- + +## surplus v2.0.0 + +(released on the 3rd of September 2023) + +!!! warning + this is an api-breaking release. see 'the great api break'. + command-line usage of surplus has not changed + +!!! information + python 3.11 or later is required due to a bug in earlier versions + [(python/cpython#88089)](https://github.com/python/cpython/issues/88089) + +complete rewrite and string query support + +### changes + +- surplus has been fully rewritten in [#19](https://github.com/markjoshwel/surplus/pull/19) +- support for string queries + ```text + $ s+ Wisma Atria + surplus version 2.0.0 + Wisma Atria + 435 Orchard Road + 238877 + Central, Singapore + ``` +- mypy will now recognise surplus as a typed module +- **python 3.11 is now the minimum version** + +### the great api break + +#### what is new + +- nominatim keys are now stored in tuple constants +- surplus exception classes are now a thing +- surplus functions now operate using a unified `Behaviour` object +- surplus functions now return a `Result` object for safer value retrieval instead of the previous + `(bool, value)` tuple +- dedicated NamedTuple classes for each query type + +#### what has been removed + +- `surplus.handle_query()` + + instead, use `.to_lat_long_coord()` on your surplus 2.x query object + +#### what has remained + +- `surplus.surplus()`, the function +- `surplus.parse_query()`, the function + +#### what has changed + +- `surplus.surplus()` + 1. `reverser` and `debug` arguments are now under the unified `surplus.Behaviour` object + 2. function now returns a `surplus.Result[str]` for safer error handling + +- `surplus.parse_query()` + 1. `query` and `debug` arguments are now under the unified `surplus.Behaviour` object + 2. function now returns a `surplus.Result[surplus.Query]` for safer error handling + +- `surplus.Latlong` + attributes `lat` and `long` have been renamed to `latitude` and `longitude` respectively + +- `surplus.Localcode` + renamed to `surplus.LocalCodeQuery` + +- `Localcode.full_length()` + renamed to `LocalCodeQuery.to_full_plus_code()`, and returns a `surplus.Result[str]` for safer + error handling + +full changelog: + +## surplus v1.1.3 + +(released on the 21st of June 2023) + +general output fixes and quality of life updates + +- ci(qc) workflow tweaks by [markjoshwel](https://github.com/markjoshwel) in [#13](https://github.com/markjoshwel/surplus/pull/13) +- cc: remove woodlands test + brackets by [markjoshwel](https://github.com/markjoshwel) in [#14](https://github.com/markjoshwel/surplus/pull/14) +- s+: display county before state by [markjoshwel](https://github.com/markjoshwel) in [#15](https://github.com/markjoshwel/surplus/pull/15) + + + +--- + +## surplus v1.1.2 + +(released on the 18th of June 2023) + +general output fixes and quality of life updates + +- do not repeat details by [markjoshwel](https://github.com/markjoshwel) in #9 +- add -v/--version flag by [markjoshwel](https://github.com/markjoshwel) in #11 + + + +--- + +## surplus v1.1.1 + +(released on the 16th of June 2023) + +### changes + +fixes and output tweaks + +- fix reverser returning a None location by [shamsu07](https://github.com/shamsu07) in #5 + +### thanks! + +- [shamsu07](https://github.com/shamsu07) made their first contribution! + + + +--- + +## surplus v1.1.0 + +(released on the 3rd of June 2023) + +short code and latitude longitude coordinate pair support! + +- code: s+ alternative shorthand script +- code: handle none/list locations +- code: query by lat long support +- code: support shortcodes with localities +- code: implement more address detail tags from nominatim +- meta: slsa 3 compliance + + + +--- + +## surplus v1.0.0 + +initial release on the 2nd of June 2023 diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 0000000..0e375b6 --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,80 @@ +# the contributor's handbook + +expected details on development workflows? see [the developer's handbook](developing.md) + +## which forge do i use? + +as at the time of writing this documentation, i am actively using both + and + +use whatever is more comfortable to you. do you not like microsoft and/or have moved away from github? +feel free to use . don't want to make an account for either? did the forge +implode and is down? okay! mail in a git patch at + +## git workflow + +1. fork the repository and branch off from the `future` branch, + or `main` if not available +2. make and commit your changes! +3. pull in any changes from upstream, and resolve any conflicts, if any +4. if needed, **commit your copyright waiver** (_see [waiving copyright](#waiving-copyright)_) +5. submit a pull request (_or mail in a patch_) + +### waiving copyright + +!!! danger "Warning" + this section is a **must** to follow if you have modified **any** unlicenced code: + + - top-level surplus files (`releaser.py`, etc) + - surplus (`src/surplus`) + - surplus Documentation (`docs/`) + - surplus on wheels (`src/surplus-on-wheels`) + - surplus on wheels: Telegram Bridge (`src/spow-telegram-bridge`) + +!!! info + the command to create an empty commit is `git commit --allow-empty` + +when contributing your first changes, please include an empty commit for a copyright +waiver using the following message (replace `Your Name` with your name or username): + +```text +Your Name Copyright Waiver + +I dedicate any and all copyright interest in this software to the +public domain. I make this dedication for the benefit of the public at +large and to the detriment of my heirs and successors. I intend this +dedication to be an overt act of relinquishment in perpetuity of all +present and future rights to this software under copyright law. + +To the best of my knowledge and belief, my contributions are either +originally authored by me or are derived from prior works which I have +verified are also in the public domain and are not subject to claims +of copyright by other parties. + +To the best of my knowledge and belief, no individual, business, +organization, government, or other entity has any copyright interest +in my contributions, and I affirm that I will not make contributions +that are otherwise encumbered. +``` + +(from ) + +for documentation contributors, if you have contributed a +[legally significant](https://www.gnu.org/prep/maintain/maintain.html#Legally-Significant) or have +repeatedly commited multiple small changes, waive your copyright with the CC0 deed +(replace `Your Name` with your name or username): + +```text +Your Name Copyright Waiver + +The person who associated a work with this deed has dedicated the work to +the public domain by waiving all of his or her rights to the work worldwide +under copyright law, including all related and neighboring rights, to the +extent allowed by law. +``` + +(from ) + +## reporting incorrect output + +TODO diff --git a/docs/developing.md b/docs/developing.md new file mode 100644 index 0000000..a954ffd --- /dev/null +++ b/docs/developing.md @@ -0,0 +1,319 @@ +# the developer’s handbook + +!!! abstract + i (mark), heavily use nix to manage my projects, either with + [devbox](https://github.com/jetpack-io/devbox) or flakes + + if you are going to develop for surplus or its' sibling projects (except surplus on wheels, + which only needs `shfmt` and `shellcheck`), i would recommend you install Nix using + [Determinate Systems' Nix Installer](https://github.com/DeterminateSystems/nix-installer): + + ```text + curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install + ``` + + if i, a very very inexperienced Nix and NixOS user to give a rundown on why to use it: + + 1. **environments and builds are reproducible** + + nix is part package manager, operating system (as NixOS), and functional programming + language. because it's functional, having X as an input will always produce Y as an output, + no matter what. even in the event of environmental, social, economic, or structural collapse + + **what does this mean for you?** + when i use `nix develop` and you use `nix develop` to start a development environment, your + version of python will be the same as my version of python. your version of go will be same + as my version of go, etc + + if i can build it, and the locked inputs of the nix flake are still available on the internet, + you can build it too + + 2. **the nix store**, located literally at `/nix/store` + it's where it stores every package you need, separate and isolated from other packages. + lets say you have a tool that needs python (3.8), and another tool that needs python (3.11). + nix store will download and store the binaries for both python installations, instead of + sharing the earliest downloaded python version for both tools + + **what does this mean for you?** + whatever project you're working on that can use nix for development environments and builds + will not dirty anything else on your system. any build dependencies of surplus provided with + `nix develop` will **not** mess up software installed for other projects or even the system. + neat, if you ask me tbh + + **tl;dr**: things will just werk with nix. but if you see all of this and go, "eh. i can manage + what i install.", then power to you! i list down exactly what prerequisite software needs to be + installed for each project anyways, so have fun! (●'◡'●) + +## surplus (and Documentation) + +### environment setup + +!!! note + all prerequisite software are available in a nix flake. if you want a reproducible environment, + run `nix develop --impure` in the repository root + + - for NixOS users, [nix-ld](https://github.com/Mic92/nix-ld) is needed. if you use flakes to + declare your system, follow accordingly. else, use `/etc/nixos/configuration.nix` + + for NixOS-on-WSL users, use [nix-ld-rs](https://github.com/nix-community/nix-ld-rs) + + once you're done installing `nix-ld` or `nix-ld-rs`, + don't forget to run `sudo nixos-rebuild switch` + +prerequisite software: + +- [Python](https://www.python.org/downloads/), 3.11 or newer +- [Hatch](https://hatch.pypa.io/latest/): dependency management and build tool + +to start a development environment: + +```text +hatch shell +``` + +for docs: + +```text +hatch -e docs shell +``` + +### workflow for python code + +TODO + +### workflow for markdown documentation + +run the documentation server with: + +```text +hatch run docs:serve +``` + +i personally don't use a linter for markdown files, if it looks good on my code editor, then +whatever. if you're going to contribute back, i ask for three things: + +- run it through a spell checker or something similar + +- line limit of 100 + +- should be readable as-is on a code editor, **not the markdown preview pane**. + + my stance is, if you can afford a fancy preview of the markdown file, use the nice-ned + documentation website. else, read it as a plaintext file + + (make it look pretty on the doc site and in plaintext) + +--- + +## surplus on wheels + +### environment setup + +!!! note + all prerequisite software are available in a nix flake. if you want a reproducible environment, + run `nix develop` in `src/surplus-on-wheels` + +prerequisite software: + +- [shfmt](https://github.com/patrickvane/shfmt): formatter +- [ShellCheck](https://www.shellcheck.net/): static analyser + +### workflow + +- formatting s+ow: + - run `shfmt s+ow > s+ow.new` + - mv `s+ow.new` into `s+ow` + sometimes when piping shfmt's output immediately into the same file + results in the file being empty :( + +- checking s+ow: + - run `shellcheck s+ow` + if there's no output, that means it passed :) + +- if commiting back into the repository, try it out on your Termux system for a day or two, + just to make sure it runs correctly + +--- + +## surplus on wheels: Telegram Bridge + +### environment setup + +!!! note + all prerequisite software are available in a nix flake. if you want a reproducible environment, + run `nix develop` in `src/spow-telegram-bridge`. it uses + [poetry2nix](https://github.com/nix-community/poetry2nix), so you won't need to run + `poetry shell` afterwards. if you've changed the `pyproject.toml` file, + just exit and re-run `nix develop` + +prerequisite software: + +- [Python](https://www.python.org/downloads/), 3.11 or newer +- [Poetry](https://python-poetry.org/): dependency management and build tool + +to start a development environment: + +```text +poetry shell +``` + +### workflow + +after modifying, + +1. `mypy bridge.py` +2. `ruff format bridge.py` +3. `ruff check bridge.py` +4. [test the binary](#workflow-for-testing-the-binary) + +if the bridge behaves nominally, [bump the version](#versioning-surplus-on-wheels-telegram-bridge) +and commit! + +--- + +## surplus on wheels: WhatsApp Bridge + +### environment setup + +!!! note + all prerequisite software are available in a nix flake. if you want a reproducible environment, + run `nix develop` in `src/spow-whatsapp-bridge` + + the flake will pull in the Android SDK and NDK for building on Termux, and as such can only be + ran on `x86_64-linux` and `x86_64-darwin` + +prerequisite software: + +- [Go](https://go.dev): 1.22 or newer +- [Android NDK](https://developer.android.com/ndk/downloads), if building for Termux + +### workflow for modifying bridge code + +the bridge's code is just modified [mdtest](https://github.com/tulir/whatsmeow/tree/main/mdtest) +code, and as such, whenever in doubt, do a diff between mdtest and the bridge code + +after modifying, + +1. [build a binary](#workflow-for-building-a-binary) +2. [test the binary](#workflow-for-testing-the-binary) +3. and if all goes well, [bump the version](#versioning-surplus-on-wheels-whatsapp-bridge) + and commit! + +### workflow for bumping dependencies + +- check with your editor, plugin, or online if there's newer patch/minor (see + [semantic versioning](https://semver.org/)) versions to update to + +- change the `go.mod` accordingly + +after bumping, + +1. [build a binary](#workflow-for-building-a-binary) +2. [test the binary](#workflow-for-testing-the-binary) +3. and if all goes well, [bump the version](#versioning-surplus-on-wheels-whatsapp-bridge) + and commit! + +### workflow for building a binary + +ensure you already have c compiler on the system (if you're using `nix develop` then yes you do), then run: + +```text +CGO_ENABLED=1 go build +``` + +nix users can alternatively run: + +```text +nix build .#native +``` + +instructions to build a Termux build are located at the +[bridges' documentation page](onwheels/whatsapp-bridge.md#anywhere-else), however nix users can run +the following instead for a reproducible, deterministic and hermetic build command: + +```text +nix build .#termux +``` +the resulting build will be in `result/spow-whatsapp-bridge` + +### workflow for testing the binary + +- test it out, making sure that you write dummy test text to `~/.cache/s+ow/message` before running + the binary + + 1. run `s+ow-whatsapp-bridge login` first + + 2. run `s+ow-whatsapp-bridge list` if you don't already have a chat ID + to send the test message to + + 3. run `s+ow-whatsapp-bridge` type or copy and paste in a `wa:`-prefixed chat ID + after it logs in, and verify it sends + +if the bridge behaves nominally, [bump the version](#versioning-surplus-on-wheels-whatsapp-bridge) +and commit! + +## workflow for versioning and tagging releases + +### versioning surplus + +format: `YEAR.MAJOR.MINOR[-PRERELEASE]` ([semantic versioning](https://semver.org/)) +example: `2024.0.0`, `2024.0.0-beta` +change: update the `__version__` variable in `src/surplus/surplus.py` + +### versioning surplus on wheels + +i've tried to make surplus on wheels as reliable as it could be given a POSIX compliant shell and +commands you'd find available on virtually every linux system, Termux included + +as such, it doesn't really follow a versioning scheme as it doesn't need to. also there's no +automatic updater for it, which would be overkill anyway + +### versioning surplus on wheels: Telegram Bridge + +format: `REVISION.YYYY.WW[+BUILD]` ([calendar versioning](https://calver.org/)) +example: `2.2024.24`, `2.2024.24+1` +change: `version` key in `src/spow-telegram-bridge/pyproject.toml` + +`REVISION` here meaning any general revision/change + +the Telegram Bridge relies on [Telethon](https://github.com/LonamiWebs/Telethon/), which also +follows [semantic versioning](https://semver.org/). so, as long as major isn't bumped, or +as long as Telegram doesn't become Discord, the MTProto APIs to talk to Telegram should be +stable. + +however because Telethon also relies on a bunch of networking libraries, it made some sense to +still do weekly builds to bump dependencies, getting pipx to download the newest compatible +dependencies as compared to dubiously running some sort of script to `pipx inject` dependencies + +under normal circumstances, a non-working version of the bridge would and **should not have a +version bump**. but for any reason if an already tagged bridge is faulty and/or erroneous in +normal/expected usage, add a revision number to the end after a period (see example above) + +### versioning surplus on wheels: WhatsApp Bridge + +format: `REVISION.YYYY.WW[+BUILD]` ([calendar versioning](https://calver.org/)) +example: `2.2024.25`, `2.2024.25+1` +change: `version` attribute of `bridge` attribute set in `src/spow-whatsapp-bridge/flake.nix` + +`REVISION` here meaning any general revision/change + +the WhatsApp Bridge relies on [whatsmeow](https://github.com/tulir/whatsmeow), a rolling release +library due to the volatile, undocumented nature of WhatsApp's multidevice API and also directly +and indirectly relies on a bunch of networking libraries: + +``` title="src/spow-whatsapp-bridge/go.mod" +--8<-- "src/spow-whatsapp-bridge/go.mod" +``` + +as such, it uses a calendar versioning scheme and is built weekly + +under normal circumstances, a non-working version of the bridge would and **should not have a +version bump**. but for any reason if an already tagged bridge is faulty and/or erroneous in +normal/expected usage, add a revision number to the end after a period (see example above) + +--- + +## i've made my changes. what now? + +if you're contributing back to surplus and/or the sibling projects, firstly, thanks! +see [the contributor's handbook](contributing.md) for what's next diff --git a/docs/fonts/Geist-Regular.ttf b/docs/fonts/Geist-Regular.ttf new file mode 100644 index 0000000..a10d58a Binary files /dev/null and b/docs/fonts/Geist-Regular.ttf differ diff --git a/docs/fonts/GeistMono-Regular.ttf b/docs/fonts/GeistMono-Regular.ttf new file mode 100644 index 0000000..a909c5d Binary files /dev/null and b/docs/fonts/GeistMono-Regular.ttf differ diff --git a/docs/fonts/GeistMonoVF.woff2 b/docs/fonts/GeistMonoVF.woff2 new file mode 100644 index 0000000..fb2f024 Binary files /dev/null and b/docs/fonts/GeistMonoVF.woff2 differ diff --git a/docs/fonts/GeistVF.woff2 b/docs/fonts/GeistVF.woff2 new file mode 100644 index 0000000..9983e92 Binary files /dev/null and b/docs/fonts/GeistVF.woff2 differ diff --git a/docs/fonts/LICENSE.txt b/docs/fonts/LICENSE.txt new file mode 100644 index 0000000..8d003fe --- /dev/null +++ b/docs/fonts/LICENSE.txt @@ -0,0 +1,92 @@ +Copyright (c) 2023 Vercel, in collaboration with basement.studio + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION AND CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..4a63b95 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,42 @@ +# surplus (s+) + +surplus (s+) is a Python script to convert [Google Maps Plus Codes](https://maps.google.com/pluscodes/) +to iOS Shortcuts-like shareable text + +!!! tip + termux users can consider [surplus on wheels](onwheels/index.md), a sibling project that allows + you to run surplus regularly throughout the day and send it to someone on a messaging platform + +!!! important + python 3.11 or later is required due to a bug in earlier versions + [(python/cpython#88089)](https://github.com/python/cpython/issues/88089) + +install surplus with pip, or [pipx](https://pipx.pypa.io/) (recommended): + +```text +pipx install surplus +``` + +then, use the `surplus` command, or its `s+` shorthand: + +```text +$ s+ 7RGX+GJ Singapore +surplus version 2024.0.0 +Singapore Conference Hall +7 Shenton Way +068809 +Central, Singapore +``` + +the types of queries you can pass in are: + +- full-length Plus Codes + `6PH58QMF+FX` +- shortened Plus Codes / 'local codes' + `8QMF+FX Singapore` +- latitude and longitude coordinate pairs + `1.3336875, 103.7749375` +- string queries + `Wisma Atria` + +or, alternatively pass in `-` to read from stdin diff --git a/docs/licences.md b/docs/licences.md new file mode 100644 index 0000000..8820310 --- /dev/null +++ b/docs/licences.md @@ -0,0 +1,113 @@ +# licences + +## [surplus](index.md) + +**The Unlicence** + +surplus is free and unencumbered software released into the public domain: + +``` title="src/surplus/UNLICENCE" +--8<-- "src/surplus/UNLICENCE" +``` + +however, the dependencies surplus relies on are licenced under different, but still permissive +and open-source licences: + +- [**geopy**](https://pypi.org/project/geopy/) — + Python Geocoding Toolbox + MIT Licence + + - [**geographiclib**](https://pypi.org/project/geographiclib/) — + The geodesic routines from GeographicLib + MIT Licence + +- [**pluscodes**](https://pypi.org/project/pluscodes/) — + Compute Plus Codes (Open Location Codes) + Apache 2.0 + +--- + +## [surplus on wheels](onwheels/index.md) + +**The Unlicence** + +surplus on wheels is free and unencumbered software released into the public domain: + +``` title="src/surplus-on-wheels/UNLICENCE" +--8<-- "src/surplus-on-wheels/UNLICENCE" +``` + +--- + +## [surplus on wheels: WhatsApp Bridge](onwheels/whatsapp-bridge.md) + +**Mozilla Public Licence 2.0** + +the s+ow WhatsApp Bridge is based off of mdtest code from the +[whatsmeow](https://github.com/tulir/whatsmeow) project, which is licenced under the Mozilla +Public Licence 2.0: + +``` title="src/spow-whatsapp-bridge/LICENCE" +--8<-- "src/spow-whatsapp-bridge/LICENCE" +``` + +the direct dependencies s+ow-whatsapp-bridge relies on are licenced under different, but still +permissive and open-source licences: + +- [**whatsmeow**](https://github.com/tulir/whatsmeow) — + Go library for the WhatsApp web multidevice API + Mozilla Public Licence 2.0 + +--- + +## [surplus on wheels: Telegram Bridge](onwheels/telegram-bridge.md) + +**The Unlicence** + +the s+ow Telegram Bridge is free and unencumbered software released into the public domain: + +``` title="src/spow-telegram-bridge/UNLICENCE" +--8<-- "src/spow-telegram-bridge/UNLICENCE" +``` + +however, the direct dependencies surplus relies on are licenced under different, but still +permissive and open-source licences: + +- [**Telethon**](https://pypi.org/project/Telethon/) — + Pure Python 3 MTProto API Telegram client library, for bots too! + MIT Licence + +--- + +## [surplus documentation](index.md) + +**CC0 1.0 Universal** + +the textual contents of surplus documentation by [Mark Joshwel](https://joshwel.co) is marked +with [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/). +to view a copy of this licence, visit + +``` title="docs/CC0" +--8<-- "docs/CC0" +``` + +the fonts the documentation website relies on are licenced under different, but still +permissive and open-source licences: + +- [**Geist and Geist Mono**](https://github.com/vercel/geist-font) + SIL Open Font Licence 1.1 + + ``` title="docs/fonts/LICENSE.txt" + --8<-- "docs/fonts/LICENSE.txt" + ``` + +the direct software dependencies the documentation are also licenced under different, but still +permissive and open-source licences: + +- [**mkdocs-material**](https://squidfunk.github.io/mkdocs-material/) — + Documentation that simply works + MIT Licence + +- [**mkdocs**](https://www.mkdocs.org/) — + Project documentation with Markdown + BSD-2-Clause Licence diff --git a/docs/links.md b/docs/links.md new file mode 100644 index 0000000..a0940fa --- /dev/null +++ b/docs/links.md @@ -0,0 +1,59 @@ +# backup links + +for when first-party links like and are down: + +## surplus + +``` title="Primary Link" +https://forge.joshwel.co/mark/surplus.git +``` + +``` title="Alternative Link" +https://github.com/markjoshwel/surplus.git +``` + +## surplus on wheels + +- shell script + + ``` title="Primary Link" + https://surplus.joshwel.co/spow.sh + ``` + + ``` title="Alternative Link" + https://raw.githubusercontent.com/markjoshwel/surplus/main/src/surplus-on-wheels/s+ow + ``` + +- termux installation script + + ``` title="Primary Link" + https://surplus.joshwel.co/termux.sh + ``` + + ``` title="Alternative Link" + https://raw.githubusercontent.com/markjoshwel/surplus/main/src/surplus-on-wheels/install.sh + ``` + +## surplus on wheels: Telegram Bridge + +- install/update script: + + ``` title="Primary Link" + https://surplus.joshwel.co/telegram.sh + ``` + + ``` title="Alternative Link" + https://raw.githubusercontent.com/markjoshwel/surplus/main/src/spow-telegram-bridge/install.sh + ``` + +## surplus on wheels: WhatsApp Bridge + +- install/update script: + + ``` title="Primary Link" + https://surplus.joshwel.co/whatsapp.sh + ``` + + ``` title="Alternative Link" + https://raw.githubusercontent.com/markjoshwel/surplus/main/src/spow-whatsapp-bridge/install.sh + ``` diff --git a/docs/onwheels/bridges.md b/docs/onwheels/bridges.md new file mode 100644 index 0000000..9624ab9 --- /dev/null +++ b/docs/onwheels/bridges.md @@ -0,0 +1,58 @@ +# surplus on wheel bridges + +## official bridges + +there are two currently “official” bridges: + +- [surplus on wheels: WhatsApp Bridge](whatsapp-bridge.md) +- [surplus on wheels: Telegram Bridge](telegram-bridge.md) + +## bring your own bridge + +### an informal specification + +s+ow bridges are relatively simple as they are: + +1. an executable or script + +2. that reads in `SPOW_TARGETS` given by surplus to the bridge, using the standard input (stdin) + stream + + 1. bridges do not need to account for the possibility of multiple lines sent to stdin + + 2. bridges should account for the possibility of comma and space (`", "` instead of just `","`) + delimited targets, and strip each target of preceding and trailing whitespace + + 3. bridges should recognise a platform based on a prefix + (e.g. `wa:` for WhatsApp, `tg:` for Telegram, etc.) + +3. reads `SPOW_MESSAGE` (`~/.cache/spow/message`) for the message content + +notes: + +1. stderr and stdout are redirected to s+ow’s error and output logs respectively unless the + `-p / --private` flag is passed to surplus + +2. any errors encountered by the bridge should always result in a non-zero return. error logs will + show the exact error code, so feel free to use other numbers than 1 + +3. persistent data such as credentials and session data storage are to be handled by the + bridge itself. consider storing them in `$HOME/.local/share//`, or wherever + appropriate + +### example + +if i were to recommend an example on a basic bridge implementation, it would be the +[Telegram Bridge](telegram-bridge.md): + +```python title="src/spow-telegram-bridge/bridge.py" +--8<-- "src/spow-telegram-bridge/bridge.py" +``` + +!!! note + the feature of deleting the last sent message (`--delete-last`) is a non-standard feature for + bridges, and was simply a use case i personally needed. if you're going to implement a bridge, + all you really need is the ability to `login`, `logout`, and [send a message](#an-informal-specification) + + you can add other features as per the needs of your platform, like how the WhatsApp Bridge has + a `pair-phone` subcommand, or per your use case needs, like in the Telegram Bridge's `--delete-last`. diff --git a/docs/onwheels/emulating-termux-location.md b/docs/onwheels/emulating-termux-location.md new file mode 100644 index 0000000..89de29b --- /dev/null +++ b/docs/onwheels/emulating-termux-location.md @@ -0,0 +1,43 @@ +# emulating `termux-location` + +to bodge surplus on wheels (s+ow) on non-Termux systems + +!!! note + dummy admonition for colour matching + +!!! warning + dummy admonition for colour matching + +`termux-location`, part of [Termux:API](https://wiki.termux.com/wiki/Termux:API), gets the device's +location via android apis and returns a json response through stdout: + +```text +{ + "latitude": 1.3277513, + "longitude": 103.678317, + "altitude": 51.6298828125, + "accuracy": 48.46337890625, + "vertical_accuracy": 38.4659423828125, + "bearing": 0.0, + "speed": 0.0, + "elapsedMs": 28, + "provider": "gps" +} +``` + +see for more information + +## implementing for surplus on wheels (s+ow) + +s+ow will call the command a total of six times, being three pairs of parallel +`$LOCATION_CMD -p "network"` and `$LOCATION_CMD -p "gps"` invocations, before deciding after +exhausting all six runs on which output to choose, if any command runs were successful + +even if somewhere in the termux-location implementation fails, it always (begrudgingly) returns +zero. s+ow will treat the invocation of the command as successful if there is **any output** to +the standard output (stdout) stream + +## implementing for surplus (s+) + +s+, when passed `--t / --using-termux-location`, will consume stdin, parse it as json and then +attempt to retrieve the `latitude` and `longitude` keys as floating point numbers diff --git a/docs/onwheels/emulating-termux-notification.md b/docs/onwheels/emulating-termux-notification.md new file mode 100644 index 0000000..d8b0825 --- /dev/null +++ b/docs/onwheels/emulating-termux-notification.md @@ -0,0 +1,46 @@ +# emulating `termux-notification` + +to bodge surplus on wheels (s+ow) on non-Termux systems + +`termux-notification`, part of [Termux:API](https://wiki.termux.com/wiki/Termux:API), sends out an +android notification + +without `termux-notification`, s+ow will still run as it doesn't use `set -e` and very carefully +handles all command invocations, with `termux-notification` being the graceful exception\ + +however, if you would like to emulate it, make an executable globally reachable with the same name + +s+ow uses the command as such: + +```shell +termux-notification \ + --priority "default" \ + --title "surplus on wheels: No bridges" \ + --content "No '$SPOW_BRIDGES' file; message is not sent." +``` + +```shell +termux-notification \ + --priority "min" \ + --ongoing \ + --id "s+ow" \ + --title "surplus on wheels" \ + --content "s+ow has started running." +``` + +```shell +termux-notification \ + --priority "min" \ + --id "s+ow" \ + --title "surplus on wheels" \ + --content ... +``` + +```shell +termux-notification \ + --priority "default" \ + --title "surplus on wheels has errored" \ + --content ... +``` + +see for more information diff --git a/docs/onwheels/index.md b/docs/onwheels/index.md new file mode 100644 index 0000000..c87ede4 --- /dev/null +++ b/docs/onwheels/index.md @@ -0,0 +1,329 @@ +# surplus on wheels (s+ow) + +surplus on wheels is a pure shell script to get your location using +[termux-location](https://wiki.termux.com/wiki/Termux-location), process it through surplus, and +send it to messaging service or wherever using “bridges” + +surplus was made to emulate sending your location through the iOS Shortcuts app, and surplus on +wheels complements it by running surplus automatically using a cron job. +(but using it manually also works!) + +## installing + +!!! important + s+ow is a Termux-first script, and will not work anywhere else unless you have + a utility that emulates [termux-location](https://wiki.termux.com/wiki/termux-location) + on `$PATH` alongside bridges that supports your platform + +there are two notable ways to install s+ow: + +1. [as a standalone script](#as-a-standalone-script) +2. or, [as a cron job](#as-a-cron-job) + +there is also an [installation script](#using-installation-scripts) for quickly getting +started from a _fresh_ termux installation + +### as a standalone script + +1. firstly install python and termux-api if you haven't already: + + ```text + pkg install python termux-api + ``` + + also install the accompanying Termux:API app from [F-Froid](https://f-droid.org/en/packages/com.termux.api/) + +2. install pipx if you haven't already: + + ```text + pip install pipx + ``` + +3. install surplus: + + ```text + pipx install surplus + ``` + +4. install surplus on wheels: + + ```text + mkdir -p ~/.local/bin/ + wget -O ~/.local/bin/s+ow https://surplus.joshwel.co/spow.sh + chmod +x ~/.local/bin/s+ow + ``` + + !!! note + if `wget` throws a 404, see [backup links](../links.md) + + if `~/.local/bin` is not in your `$PATH`, add the following to your shell's rc file: + + ```shell + export PATH="$HOME/.local/bin:$PATH" + ``` + +et voilà! s+ow is now setup. to actually send the message to a messaging platform, +[install an appropriate bridge](bridges.md) + +### as a cron job + +!!! important + these instructions rely on following the [previous instructions](#as-a-standalone-script) + +1. install necessary packages to run cron jobs: + + ```text + pkg install cronie termux-services + ``` + +2. restart termux and start the cron service: + + ```text + sv-enable cron + ``` + +3. set up the cron job: + + run the following command: + + ```text + crontab -e + ``` + + and add the following text: + + ```text + 59 * * * * bash -l -c "(SPOW_TARGETS="" SPOW_CRON=y s+ow)" + ``` + + !!! important + minimally fill in the `SPOW_TARGETS` variable before running s+ow. + [(see usage for more info)](#usage) + + this will run s+ow every hour, a minute before the hour + + modify the variables as per your needs. + see [usage](#usage) for more information + + et voilà! s+ow will now send a message every hour. feel free to experiment with the cron + job to your liking. see [crontab.guru](https://crontab.guru/) if you’re new to cron jobs + +if you haven’t already, [install an appropriate bridge](bridges.md) to actually send a +message to a messaging platform + +### using installation scripts + +!!! warning + these scripts assume you're starting from a fresh base installation of Termux. + if you have already cron jobs, then manually carry out the instructions in + '[as a cron job](#as-a-cron-job)' + +!!! important + if not installed already, install + [Termux:API from F-Droid](https://f-droid.org/en/packages/com.termux.api/), **not the Play Store** + +1. setup s+ow: + + ```text + wget -O- https://surplus.joshwel.co/termux.sh | sh + ``` + + !!! note + if `wget` throws a 404, see [backup links](../links.md) + +2. restart termux! + +3. and finally, [set up a cron job](#as-a-cron-job) from step 3 onwards ('set up the cron job') + +## usage + +### environment variables + +s+ow's behaviour can be customised environment variables, with `SURPLUS_CMD` being the only +required variable: + +1. `SPOW_TARGETS` + a single line of comma-delimited chat IDs with bridge prefixes + + ```text + wa:000000000000000000@g.us,tg:-0000000000000000000,... + ``` + + in the example above, the WhatsApp chat ID is `wa:`-prefixed as recognised by the + [spow-whatsapp-bridge](whatsapp-bridge.md), and the + Telegram chat ID is `tg:`-prefixed as recognised by the + [spow-telegram-bridge](telegram-bridge.md) + +2. `SPOW_CRON` (optional) + set as non-empty to declare that s+ow is being run as a cron job + + if running as a cron job, start s+ow one minute earlier than intended to account for the time + it takes to run `termux-location` and `surplus`. s+ow assumes this and delays itself + appropriately + + setting it to `n` will also be treated as if it were empty + +3. `SPOW_PRIVATE` (optional) + set as non-empty to discard all logs when s+ow is done: + + - `$HOME/.cache/s+ow/out.log` will be set to `/dev/null` + - `$HOME/.cache/s+ow/err.log` will be set to `/dev/null` + - `$HOME/.cache/s+ow/location.net.json` will be cleared after use locating the device + - `$HOME/.cache/s+ow/location.gps.json` will be cleared after use locating the device + - `$HOME/.cache/s+ow/location.json` will be cleared after use locating the device + - `$HOME/.cache/s+ow/surplus.out.log` will be cleared after use generating the message + - `$HOME/.cache/s+ow/surplus.err.log` will be set to `/dev/null` + - `$HOME/.cache/s+ow/message` will be cleared after all bridges has sent the message + + !!! warning + the only file not cleared is s+ow's last successful message file, `$HOME/.cache/s+ow/last`, + as s+ow uses this as the first fallback message if it couldn't locate the device in time. + if you're fine with using the `LOCATION_FALLBACK` string, feel free to modify your + cron job to remove this file after running s+ow + + setting it to `n` will also be treated as if it were empty + +4. `SURPLUS_CMD` (optional) + the custom invocation used when calling surplus, modify this if you want to add certain flags + + this defaults to `surplus -td` + + !!! warning + when overriding, ensure you also have `-td` (`--using-termux-location` and `--debug`) in + your custom invocation! + +5. `LOCATION_CMD` (optional) + the custom invocation used when calling `termux-location`, modify this if you want to bodge + together surplus on wheels on non-termux systems. + see ([emulating `termux-location`](emulating-termux-location.md)) for more information + + this defaults to `termux-location` + +6. `LOCATION_PRIORITISE_NETWORK` (optional) + set as non-empty to declare that s+ow can just use network location instead of GPS + if GPS is taking too long. + you should only turn this on if punctuality means that much to you, or you’re in a + country with cell towers close by or everywhere, like Singapore + + the JIDs can be obtained by sending a message to the user/group, while running + `s+ow mdtest`, and examining the output for your message. JIDs are email address-like + strings + + setting it to `n` will also be treated as if it were empty + +7. `LOCATION_TIMEOUT` (optional) + set as a number to override the default first location timeout of `50` + +8. `LOCATION_FALLBACK` (optional) + a string that can be formatted with three numbers using `%d`: + + 1. s+ow's status + 2. number of location attempts before giving up + 3. type of message sent + + see [details on notification numbers](#details-on-notification-numbers) for the meanings of + each number. 'a', 'b' and 'c' map to `A`, `B` and `C` + + defaults to `%d%d%d?` + +### faking locations + +> sometimes you gotta do what you gotta do + +you can fake your s+ow messages by either: + +1. setting a dummy `last` file in s+ow cache + + `$HOME/.cache/s+ow/last` is used as the fallback response when a part of s+ow (either + `termux-location` or `surplus` errors out). you can set this file to whatever you want + and just turn off location on your device + +2. setting a `fake` file in s+ow cache + + !!! warning + s+ow uses the `read` command to read the file. as such, it is possible for s+ow to + prematurely stop reading the file if the file does not contain a trailing newline. + + you can also write text to `$HOME/.cache/s+ow/fake` to fake upcoming messages. the file + is delimited by empty lines. as such, arrange the file like so: + + ```text + The Clementi Mall + 3155 Commonwealth Avenue West + Westpeak Terrace + 129588 + Southwest, Singapore + + Westgate + 3 Gateway Drive + Jurong East + 608532 + Southwest, Singapore + + ... + + ``` + + on every run of s+ow, the first group of lines will be consumed, and the file will be + updated with the remaining lines. if the file is empty, it will be deleted + +### details on notification numbers + +after each run, or if s+ow had to use a location fallback string, s+ow notifies you: + +!!! abstract "surplus on wheels" + Run has finished. + + Singapore Conference Hall + 7 Shenton Way + 068809 + Central, Singapore + + (A, B, C, D) + [lc:W sp:X sm:Y - Z] + +!!! abstract "surplus on wheels has errored" + (A, B, C, D) + [lc:W sp:X sm:Y - Z] + +the top line denotes general statuses: + +- `A`: s+ow's status + - `0` is nominal + - `1` is a termux-location error + - `2` is a surplus error + - `3` is a bridge/message send error +- `B`: number of location attempts before giving up +- `C`: type of message sent + - `0` for freshly made sharetext + - `1` for recycling a previous successful location sharetext (`last` file) + - `2` for using fallback template +- `D`: number of bridge failures +- `E`: each bridge's return code + +the bottom line details on how long s+ow spent on each stage: + +- `W`: time to locate +- `X`: time to run surplus +- `Y`: time to send message(s) +- `Z`: total run time + +## help! a bridge isn't working! + +cool. do the following: + +1. log out and log back in and try again + +2. if that didn't fix it, update/reinstall the bridge and try again + +3. run the bridge's executable directly to see if there's any connection issues + look at your bridge's installation instructions to find out where it's located at. + or, use the `which` command + +4. if it connected successfully, or you see no errors, try typing in one of the targets you've set + in `SPOW_TARGETS` for the bridge, and then press the enter/return key + +!!! failure + on the off chance you reinstalled the bridge, and it still failed either step 3 or 4, the bridge + itself is faulty. file a bug report/issue with the bridge's project page or maintainer and tell + them where it failed (was it connecting to the messaging service? or failure to send a message?) diff --git a/docs/onwheels/telegram-bridge.md b/docs/onwheels/telegram-bridge.md new file mode 100644 index 0000000..44ba868 --- /dev/null +++ b/docs/onwheels/telegram-bridge.md @@ -0,0 +1,101 @@ +# surplus on wheels: Telegram Bridge + +Telegram Bridge for surplus on wheels (s+ow) + +s+ow bridges are defined in a file named `$HOME/.s+ow-bridges`. each command in the file is run, +and comma-seperated target chat IDs are passed using stdin. + +this bridge recognises targets prefixed with `tg:`. + +```text +tg:,... +``` + +## installation + +!!! important + the following instructions implies that [surplus](../index.md) and [surplus on wheels](bridges.md) + have already been installed + +1. install prerequisite software if not installed: + + ```text + pkg install git + ``` + + ```text + pip install pipx + ``` + +2. install spow-telegram-bridge: + + ```text + wget -O- https://surplus.joshwel.co/telegram.sh | sh + ``` + + !!! note + if `wget` throws a 404, see [backup links](../links.md) + +3. add the following to your `$HOME/.s+ow-bridges` file: + + ```text + SPOW_TELEGRAM_API_HASH="" SPOW_TELEGRAM_API_ID="" s+ow-telegram-bridge + ``` + + fill in SPOW_TELEGRAM_API_HASH and SPOW_TELEGRAM_API_ID accordingly. + see the [Telethon docs](https://docs.telethon.dev/en/stable/basic/signing-in.html) for + more information + +to keep up to date, look at [updating](#updating) to set up a daily update cron job: + +## updating + +the installation script also sets up a shell script under the `s+ow-telegram-bridge-update` command + +```text +s+ow-telegram-bridge-update +``` + +to do this automatically, make a cron job with `crontab -e` +and make a new line with the following text: + +```text +0 0 * * * bash -l -c "s+ow-telegram-bridge-update" +``` + +this cron job will run the command every day at midnight + +## usage + +- `s+ow-telegram-bridge` + normal usage; sends latest message to tg:-prefixed targets given in stdin + +- `s+ow-telegram-bridge login` + logs in to Telegram + +- `s+ow-telegram-bridge logout` + logs out of Telegram + +- `s+ow-telegram-bridge list` + lists all chats and their IDs + +optional arguments: + +- `--silent` + asks telegram to send message silently +- `--delete-last` + deletes last location message to prevent clutter + +## versioning scheme + +from `v2.2024.27`, the Telegram Bridge will automatically release a new version once a week if there +are updates to its dependencies + +as such, the bridge is now versioned with a modified calendar versioning scheme of +`MAJOR.YEAR.ISOWEEK`, where the `MAJOR` version segment will be bumped with codebase changes, whereas +the `YEAR` and `ISOWEEK` segments will represent the time of which the release was built at + +## licence + +the s+ow Telegram Bridge is free and unencumbered software released into the public domain. +for more information, see [licences](../licences.md). diff --git a/docs/onwheels/whatsapp-bridge.md b/docs/onwheels/whatsapp-bridge.md new file mode 100644 index 0000000..a125f7b --- /dev/null +++ b/docs/onwheels/whatsapp-bridge.md @@ -0,0 +1,210 @@ +# surplus on wheels: WhatsApp Bridge + +WhatsApp Bridge for surplus on wheels (s+ow) + +s+ow bridges are defined in a file named `$HOME/.s+ow-bridges`. each command in the file is run, +and comma-seperated target chat IDs are passed using stdin. + +this bridge recognises targets prefixed with `wa:`. + +```text +wa:,... +``` + +## installation + +### from a pre-built binary + +```text +wget -O- https://surplus.joshwel.co/whatsapp.sh | sh +``` + +!!! note + if `wget` throws a 404, see [backup links](../links.md) + +### building from source + +#### on Termux + +1. clone the repository at either `https://forge.joshwel.co/mark/surplus` or + `https://github.com/markjoshwel/surplus`, and navigate to `src/spow-whatsapp-bridge` within the + cloned repository + + ```text + git clone https://forge.joshwel.co/mark/surplus + cd surplus/src/spow-whatsapp-bridge + ``` + +2. build the bridge: + + ```text + go build + ``` + + for compatibility with the documentations' instructions as-is, rename the built binary to + `s+ow-whatsapp-bridge` + + ```text + mv spow-whatsapp-bridge s+ow-whatsapp-bridge + ``` + +3. send the built binary over to your Termux environment, and then move it into the + `$HOME/.local/bin/` folder. if it doesn't exist, make it with `mkdir` and ensure that the folder + is in your `PATH` variable either using your `.profile`, `.bashrc` or whatever file is sourced + when opening your shell + +#### anywhere else + +for usage on Termux, see if the [Android NDK](https://developer.android.com/ndk/downloads) supports your platform + +1. grab a copy of the NDK, and extract it somewhere. navigate to + `/toolchains/llvm/prebuilt//bin` and look for a suitable `clang` + executable, as it will be your CGO compiler + + ``` + m@csp:~/android-ndk-r26d/toolchains/llvm/prebuilt/linux-x86_64/bin$ ls *clang + aarch64-linux-android21-clang aarch64-linux-android30-clang ... + aarch64-linux-android22-clang aarch64-linux-android31-clang + aarch64-linux-android23-clang aarch64-linux-android32-clang + aarch64-linux-android24-clang aarch64-linux-android33-clang + aarch64-linux-android25-clang aarch64-linux-android34-clang + aarch64-linux-android26-clang armv7a-linux-androideabi21-clang + aarch64-linux-android27-clang armv7a-linux-androideabi22-clang + aarch64-linux-android28-clang armv7a-linux-androideabi23-clang + aarch64-linux-android29-clang armv7a-linux-androideabi24-clang + ``` + + the example output is not exhaustive and is cut short for brevity and example, do take a look + at your downloaded NDK archive for what executables are available to you + + many executables are present, so choose a) what architecture you will build for (more often + than not it's `aarch64`), and b) what target android api are you building for + + if you're building for yourself, pick an api level/version that correlates to your devices' + android version. as an example, my device runs on an ARM processor (`aarch64`) and runs Android 14, + which is api level 34. (`android34`) as such, i would use the `aarch64-linux-android34-clang` + binary + +2. clone the repository at either `https://forge.joshwel.co/mark/surplus` or + `https://github.com/markjoshwel/surplus`, and navigate to `src/spow-whatsapp-bridge` within the + cloned repository + + ```text + git clone https://forge.joshwel.co/mark/surplus + cd surplus/src/spow-whatsapp-bridge + ``` + +3. build the bridge: + + ```text + CC="" GOOS=android GOARCH=arm64 CGO_ENABLED=1 go build + ``` + + for compatibility with the documentations' instructions as-is, rename the built binary to + `s+ow-whatsapp-bridge` + + ```text + mv spow-whatsapp-bridge s+ow-whatsapp-bridge + ``` + +4. send the built binary over to your Termux environment, and then move it into the + `$HOME/.local/bin/` folder. if it doesn't exist, make it with `mkdir` and ensure that the folder + is in your `PATH` variable either using your `.profile`, `.bashrc` or whatever file is sourced + when opening your shell + +### post-installation setup + +1. log into WhatsApp: + + ```text + s+ow-whatsapp-bridge login + ``` + + give it a minute or two to sync your history. once the screen stops scrolling, you can safely + exit with Ctrl+D or Ctrl+C. + +2. find out what chats you want the bridge to target: + + ```text + s+ow-whatsapp-bridge list + ``` + + !!! note + for sending to individuals: their IDs are their internationalised phone numbers ending in + `@s.whatsapp.net` + + example: `+65 9123 4567` is `6591234567@s.whatsapp.net` + + then, note these down, prefixed with `wa:`, to them to your `SPOW_TARGETS` variable in your + s+ow cron job + +3. finally, add the following to your $HOME/.s+ow-bridges file: + + ```text + s+ow-whatsapp-bridge + ``` + +## updating + +to keep updated as [whatsmeow](https://github.com/tulir/whatsmeow/), the library the bridge depends +on, has to keep updated with the WhatsApp web multidevice API, you can either: + +1. [rebuild when a weekly release comes out](#building-from-source), +2. [or rely on the weekly continuous deployment builds](#from-a-pre-built-binary) + +to use the weekly builds without building from scratch every time, + +!!! note + this will pull the latest binary, around 20 megabytes in size, every day. if your network or + data plan may not take kindly to this, feel free to adjust the cron entry as you wish, or to + one that runs once a week instead: + + ```text + 0 0 * * 0 bash -l -c "s+ow-whatsapp-bridge-update" + ``` + +## usage + +- `s+ow-whatsapp-bridge` + normal usage; sends latest message to wa:-prefixed targets given in stdin + +- `s+ow-whatsapp-bridge login` + logs in to WhatsApp + +- `s+ow-whatsapp-bridge pair-phone` + logs in to WhatsApp using a phone number + +- `s+ow-whatsapp-bridge reconnect` + reconnects the client + +- `s+ow-whatsapp-bridge logout` + logs out of WhatsApp + +- `s+ow-whatsapp-bridge list` + lists all group chats and their IDs. + + for sending to individuals: their IDs are their internationalised phone numbers ending in + `@s.whatsapp.net` + + example: `+65 9123 4567` is `6591234567@s.whatsapp.net` + +## verifying a pre-built binary + +!!! note + if you installed the bridge through an installation script, it would have already + + and if the script or `s+ow-whatsapp-bridge-update` throws an error about failing verification, + you can use the environment variable `` + +TODO + +## versioning scheme + +from `v2.2024.25`, the bridge is now versioned with a modified calendar versioning scheme of +`MAJOR.YEAR.ISOWEEK`, where the `MAJOR` version segment will be bumped with codebase changes, whereas +the `YEAR` and `ISOWEEK` segments will represent the time of which the release was built at + +## licence + +the s+ow Telegram Bridge is free and unencumbered software released into the public domain. +for more information, see [licences](../licences.md). diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..7c43eca --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,212 @@ +@font-face { + font-family: "Geist"; + src: url('../fonts/GeistVF.woff2') format('woff2'), + url('../fonts/Geist-Regular.ttf') format('truetype'); +} +@font-face { + font-family: "Geist Mono"; + src: url('../fonts/GeistMonoVF.woff2') format('woff2'), + url('../fonts/GeistMono-Regular.ttf') format('truetype'); +} + +:root { + --md-text-font: "Geist"; + --md-code-font: "Geist Mono"; + --md-hue: 180deg; +} + +* { + text-rendering: geometricprecision !important; + -webkit-font-smoothing: antialiased; +} + +[data-md-color-scheme="default"] { + color-scheme: light; + + --md-sys-color-primary: rgb(51 71 65); + --md-sys-color-surface-tint: rgb(78 99 92); + --md-sys-color-on-primary: rgb(255 255 255); + --md-sys-color-primary-container: rgb(95 116 109); + --md-sys-color-on-primary-container: rgb(255 255 255); + --md-sys-color-secondary: rgb(61 69 66); + --md-sys-color-on-secondary: rgb(255 255 255); + --md-sys-color-secondary-container: rgb(110 118 115); + --md-sys-color-on-secondary-container: rgb(255 255 255); + --md-sys-color-tertiary: rgb(0 73 93); + --md-sys-color-on-tertiary: rgb(255 255 255); + --md-sys-color-tertiary-container: rgb(65 124 147); + --md-sys-color-on-tertiary-container: rgb(255 255 255); + --md-sys-color-error: rgb(124 37 0); + --md-sys-color-on-error: rgb(255 255 255); + --md-sys-color-error-container: rgb(200 77 28); + --md-sys-color-on-error-container: rgb(255 255 255); + --md-sys-color-background: rgb(251 249 247); + --md-sys-color-on-background: rgb(27 28 27); + --md-sys-color-surface: rgb(251 249 247); + --md-sys-color-on-surface: rgb(27 28 27); + --md-sys-color-surface-variant: rgb(222 228 224); + --md-sys-color-on-surface-variant: rgb(62 68 66); + --md-sys-color-outline: rgb(90 96 94); + --md-sys-color-outline-variant: rgb(118 124 121); + --md-sys-color-shadow: rgb(0 0 0); + --md-sys-color-scrim: rgb(0 0 0); + --md-sys-color-inverse-surface: rgb(48 49 48); + --md-sys-color-inverse-on-surface: rgb(242 240 239); + --md-sys-color-inverse-primary: rgb(181 203 195); + --md-sys-color-primary-fixed: rgb(100 121 114); + --md-sys-color-on-primary-fixed: rgb(255 255 255); + --md-sys-color-primary-fixed-dim: rgb(76 96 90); + --md-sys-color-on-primary-fixed-variant: rgb(255 255 255); + --md-sys-color-secondary-fixed: rgb(110 118 115); + --md-sys-color-on-secondary-fixed: rgb(255 255 255); + --md-sys-color-secondary-fixed-dim: rgb(86 94 90); + --md-sys-color-on-secondary-fixed-variant: rgb(255 255 255); + --md-sys-color-tertiary-fixed: rgb(65 124 147); + --md-sys-color-on-tertiary-fixed: rgb(255 255 255); + --md-sys-color-tertiary-fixed-dim: rgb(36 99 121); + --md-sys-color-on-tertiary-fixed-variant: rgb(255 255 255); + --md-sys-color-surface-dim: rgb(219 218 216); + --md-sys-color-surface-bright: rgb(251 249 247); + --md-sys-color-surface-container-lowest: rgb(255 255 255); + --md-sys-color-surface-container-low: rgb(245 243 242); + --md-sys-color-surface-container: rgb(239 238 236); + --md-sys-color-surface-container-high: rgb(233 232 230); + --md-sys-color-surface-container-highest: rgb(228 226 225); + + --md-hue: 139.2deg; + --md-default-fg-color: var(--md-sys-color-primary); + --md-default-bg-color: var(--md-sys-color-surface); + + /* primary colours */ + --md-primary-fg-color: var(--md-sys-color-primary); + --md-primary-fg-color--light: var(--md-sys-color-inverse-primary); + --md-primary-fg-color--dark: var(--md-sys-color-primary-container); + --md-primary-bg-color: var(--md-sys-color-surface); + --md-primary-bg-color--light: var(--md-sys-color-surface-dim); + + /* accent (interactable) colours */ + --md-accent-fg-color: var(--md-sys-color-tertiary); + --md-accent-bg-color: var(--md-sys-color-on-tertiary); + --md-accent-bg-color--light: var(--md-sys-color-surface-dim); + + /* typesetting colours */ + --md-typeset-color: var(--md-sys-color-on-surface); + --md-typeset-a-color: var(--md-sys-color-tertiary); + --md-typeset-del-color: var(--md-sys-color-on-error-container); + --md-typeset-ins-color: var(--md-sys-color-on-primary-container); + --md-typeset-kbd-color: var(--md-sys-color-surface-container-lowest); + --md-typeset-kbd-accent-color: var(--md-sys-color-surface-container); + --md-typeset-kbd-border-color: var(--md-sys-color-surface-container-highest); + --md-typeset-mark-color: var(--md-sys-color-tertiary-container); + --md-typeset-table-color: var(--md-sys-color-outline); + --md-code-bg-color: var(--md-sys-color-surface-container-high); + + /* admonition colours */ + --md-admonition-fg-color: var(--md-sys-color-secondary); + --md-admonition-bg-color: var(--md-default-bg-color); + --md-warning-fg-color: var(--md-sys-color-on-error-container); + --md-warning-bg-color: var(--md-sys-color-error-container); + + /* footer colours */ + --md-footer-fg-color: var(--md-sys-color-on-surface); + --md-footer-fg-color--light: var(--md-sys-color-on-surface-variant); + --md-footer-fg-color--lighter: var(--md-sys-color-outline); + --md-footer-bg-color: var(--md-sys-color-surface-dim); + --md-footer-bg-color--dark: var(--md-sys-color-surface-container-highest); +} + +[data-md-color-scheme="slate"] { + color-scheme: dark; + + --md-sys-color-primary: rgb(185 208 199); + --md-sys-color-surface-tint: rgb(181 203 195); + --md-sys-color-on-primary: rgb(6 26 21); + --md-sys-color-primary-container: rgb(128 149 142); + --md-sys-color-on-primary-container: rgb(0 0 0); + --md-sys-color-secondary: rgb(196 205 200); + --md-sys-color-on-secondary: rgb(16 24 21); + --md-sys-color-secondary-container: rgb(138 147 143); + --md-sys-color-on-secondary-container: rgb(0 0 0); + --md-sys-color-tertiary: rgb(153 211 236); + --md-sys-color-on-tertiary: rgb(0 25 34); + --md-sys-color-tertiary-container: rgb(99 157 181); + --md-sys-color-on-tertiary-container: rgb(0 0 0); + --md-sys-color-error: rgb(255 187 164); + --md-sys-color-on-error: rgb(48 9 0); + --md-sys-color-error-container: rgb(237 104 54); + --md-sys-color-on-error-container: rgb(0 0 0); + --md-sys-color-background: rgb(19 20 19); + --md-sys-color-on-background: rgb(228 226 225); + --md-sys-color-surface: rgb(19 20 19); + --md-sys-color-on-surface: rgb(252 250 249); + --md-sys-color-surface-variant: rgb(66 72 70); + --md-sys-color-on-surface-variant: rgb(198 204 200); + --md-sys-color-outline: rgb(158 164 161); + --md-sys-color-outline-variant: rgb(126 132 129); + --md-sys-color-shadow: rgb(0 0 0); + --md-sys-color-scrim: rgb(0 0 0); + --md-sys-color-inverse-surface: rgb(228 226 225); + --md-sys-color-inverse-on-surface: rgb(41 42 41); + --md-sys-color-inverse-primary: rgb(56 76 70); + --md-sys-color-primary-fixed: rgb(209 232 223); + --md-sys-color-on-primary-fixed: rgb(2 20 16); + --md-sys-color-primary-fixed-dim: rgb(181 203 195); + --md-sys-color-on-primary-fixed-variant: rgb(38 58 52); + --md-sys-color-secondary-fixed: rgb(220 228 224); + --md-sys-color-on-secondary-fixed: rgb(11 19 16); + --md-sys-color-secondary-fixed-dim: rgb(192 200 196); + --md-sys-color-on-secondary-fixed-variant: rgb(48 56 53); + --md-sys-color-tertiary-fixed: rgb(186 234 255); + --md-sys-color-on-tertiary-fixed: rgb(0 20 27); + --md-sys-color-tertiary-fixed-dim: rgb(149 207 232); + --md-sys-color-on-tertiary-fixed-variant: rgb(0 59 76); + --md-sys-color-surface-dim: rgb(19 20 19); + --md-sys-color-surface-bright: rgb(57 57 56); + --md-sys-color-surface-container-lowest: rgb(13 14 14); + --md-sys-color-surface-container-low: rgb(27 28 27); + --md-sys-color-surface-container: rgb(31 32 31); + --md-sys-color-surface-container-high: rgb(41 42 41); + --md-sys-color-surface-container-highest: rgb(52 53 52); + + /*--md-hue: 139.2deg;*/ + --md-default-fg-color: var(--md-sys-color-primary); + --md-default-bg-color: var(--md-sys-color-surface); + + /* primary colours */ + --md-primary-fg-color: var(--md-sys-color-primary); + --md-primary-fg-color--light: var(--md-sys-color-inverse-primary); + --md-primary-fg-color--dark: var(--md-sys-color-primary-container); + --md-primary-bg-color: var(--md-sys-color-surface); + --md-primary-bg-color--light: var(--md-sys-color-surface-dim); + + /* accent (interactable) colours */ + --md-accent-fg-color: var(--md-sys-color-tertiary); + --md-accent-bg-color: var(--md-sys-color-on-tertiary); + --md-accent-bg-color--light: var(--md-sys-color-surface-dim); + + /* typesetting colours */ + --md-typeset-color: var(--md-sys-color-on-surface); + --md-typeset-a-color: var(--md-sys-color-tertiary); + --md-typeset-del-color: var(--md-sys-color-on-error-container); + --md-typeset-ins-color: var(--md-sys-color-on-primary-container); + --md-typeset-kbd-color: var(--md-sys-color-surface-container-lowest); + --md-typeset-kbd-accent-color: var(--md-sys-color-surface-container); + --md-typeset-kbd-border-color: var(--md-sys-color-surface-container-highest); + --md-typeset-mark-color: var(--md-sys-color-tertiary-container); + --md-typeset-table-color: var(--md-sys-color-outline); + --md-typeset-table-color--light: var(--md-sys-color-outline-variant); + --md-code-bg-color: var(--md-sys-color-surface-container-high); + + /* admonition colours */ + --md-admonition-fg-color: var(--md-sys-color-secondary); + --md-admonition-bg-color: var(--md-default-bg-color); + --md-warning-fg-color: var(--md-sys-color-on-error-container); + --md-warning-bg-color: var(--md-sys-color-error-container); + + /* footer colours */ + --md-footer-fg-color: var(--md-sys-color-on-surface); + --md-footer-fg-color--light: var(--md-sys-color-on-surface-variant); + --md-footer-fg-color--lighter: var(--md-sys-color-outline); + --md-footer-bg-color: var(--md-sys-color-surface-dim); + --md-footer-bg-color--dark: var(--md-sys-color-surface-container-highest); +} diff --git a/docs/stylesheets/pdf.scss b/docs/stylesheets/pdf.scss new file mode 100644 index 0000000..b7aec30 --- /dev/null +++ b/docs/stylesheets/pdf.scss @@ -0,0 +1,4 @@ +@page { + size: A4; + margin: 1.25cm; +} diff --git a/docs/using.md b/docs/using.md new file mode 100644 index 0000000..7eff7f7 --- /dev/null +++ b/docs/using.md @@ -0,0 +1,11 @@ +# the user's handbook + +TODO + +## as a command line tool + +TODO + +## as a python library + +TODO diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..db424ed --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,114 @@ +site_name: surplus Documentation +site_url: https://surplus.joshwel.co +site_author: Mark Joshwel and surplus contributors +site_description: documentation for the surplus and sibling projects + +repo_name: markjoshwel/surplus +repo_url: https://github.com/markjoshwel/surplus + +copyright: | + with with all our hearts, 2023-2024, mark joshwel and contributors
+ documentation is dedicated to the public domain with CC0 + +nav: +- about: + - surplus: "index.md" + - licences: "licences.md" + - changelog: "changelog.md" +- handbooks: + - "using.md" + - "developing.md" + - "contributing.md" +- on wheels: + - "onwheels/index.md" + - bridges: + - about bridges: "onwheels/bridges.md" + - "onwheels/telegram-bridge.md" + - "onwheels/whatsapp-bridge.md" + - "onwheels/emulating-termux-location.md" + - "onwheels/emulating-termux-notification.md" +- backup links: + "links.md" + +theme: + name: material + language: en + + features: + - navigation.tabs + - navigation.tabs.sticky + - navigation.tracking + - navigation.expand + - toc.integrate + - search.suggest + - search.highlight + - content.tabs.link + - content.code.annotation + - content.code.copy + - pymdownx.snippets + + font: false + + palette: + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Light Theme + primary: custom + accent: custom + - media: "(prefers-color-scheme: light)" + scheme: default + toggle: + icon: material/brightness-7 + name: Dark Theme + primary: custom + accent: custom + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/brightness-4 + name: System Theme + primary: custom + accent: custom + + icon: + admonition: + abstract: material/text-box-outline + tip: material/pencil-outline + note: material/information-slab-box-outline + warning: material/alert-outline + danger: material/alert-octagon-outline + + +extra_css: + - stylesheets/extra.css + +plugins: + - search + - privacy + #- git-revision-date-localized: + # enable_creation_date: true + - exporter: + formats: + pdf: + enabled: !ENV [MKDOCS_EXPORTER_PDF_ENABLED, true] + stylesheets: + - docs/stylesheets/pdf.scss + aggregator: + enabled: true + output: documentation.pdf + buttons: + - title: Download as PDF + icon: material-file-download-outline + enabled: !!python/name:mkdocs_exporter.formats.pdf.buttons.download.enabled + attributes: !!python/name:mkdocs_exporter.formats.pdf.buttons.download.attributes + +markdown_extensions: + - admonition + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences diff --git a/src/tools/docs-prebuild.py b/src/tools/docs-prebuild.py new file mode 100644 index 0000000..f01223e --- /dev/null +++ b/src/tools/docs-prebuild.py @@ -0,0 +1,23 @@ +""" +script to copy shell scripts into the docs folder for publishing + +src/surplus-on-wheels/s+ow -> docs/spow.sh +src/surplus-on-wheels/termux-s+ow-setup -> docs/termux.sh +src/spow-whatsapp-bridge/install.sh -> docs/whatsapp.sh +src/spow-telegram-bridge/install.sh -> docs/telegram.sh +""" +from pathlib import Path +from shutil import copyfile + +repo_root: Path = Path(__file__).parent.parent.parent +docs_path: Path = repo_root.joinpath("docs") + +copy_map: dict[Path, Path] = { + repo_root.joinpath("src/surplus-on-wheels/s+ow"): docs_path.joinpath("spow.sh"), + repo_root.joinpath("src/surplus-on-wheels/install.sh"): docs_path.joinpath("termux.sh"), + repo_root.joinpath("src/spow-whatsapp-bridge/install.sh"): docs_path.joinpath("whatsapp.sh"), + repo_root.joinpath("src/spow-telegram-bridge/install.sh"): docs_path.joinpath("telegram.sh"), +} + +for target, destination in copy_map.items(): + copyfile(target, destination)