docs: add mkdocs site :O
This commit is contained in:
parent
40d318bef7
commit
c6eadc6045
121
docs/CC0
Normal file
121
docs/CC0
Normal file
|
@ -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.
|
325
docs/changelog.md
Normal file
325
docs/changelog.md
Normal file
|
@ -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: <https://github.com/markjoshwel/surplus/compare/v2.2.0...v2024.0.0>
|
||||||
|
|
||||||
|
## 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**
|
||||||
|
|
||||||
|
<https://github.com/markjoshwel/surplus/compare/v2.1.1...v2.2.0>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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)
|
||||||
|
|
||||||
|
<https://github.com/markjoshwel/surplus/compare/v2.1.0...v2.1.1>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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)
|
||||||
|
|
||||||
|
<https://github.com/markjoshwel/surplus/compare/v2.0.1...v2.1.0>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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)
|
||||||
|
|
||||||
|
<https://github.com/markjoshwel/surplus/compare/v2.0.0...v2.0.1>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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: <https://github.com/markjoshwel/surplus/compare/v1.1.3...v2.0.0>
|
||||||
|
|
||||||
|
## 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)
|
||||||
|
|
||||||
|
<https://github.com/markjoshwel/surplus/compare/v1.1.2...v1.1.3>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
<https://github.com/markjoshwel/surplus/compare/v1.1.0...v1.1.1>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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!
|
||||||
|
|
||||||
|
<https://github.com/markjoshwel/surplus/compare/v1.1.0...v1.1.1>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
<https://github.com/markjoshwel/surplus/compare/v1.0.0...v1.1.0>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## surplus v1.0.0
|
||||||
|
|
||||||
|
initial release on the 2nd of June 2023
|
80
docs/contributing.md
Normal file
80
docs/contributing.md
Normal file
|
@ -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
|
||||||
|
<https://github.com/markjoshwel/surplus> and <https://forge.joshwel.co/mark/surplus>
|
||||||
|
|
||||||
|
use whatever is more comfortable to you. do you not like microsoft and/or have moved away from github?
|
||||||
|
feel free to use <https://forge.joshwel.co>. don't want to make an account for either? did the forge
|
||||||
|
implode and is down? okay! mail in a git patch at <mark@joshwel.co>
|
||||||
|
|
||||||
|
## 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 <https://unlicense.org/WAIVER>)
|
||||||
|
|
||||||
|
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 <https://creativecommons.org/publicdomain/zero/1.0/>)
|
||||||
|
|
||||||
|
## reporting incorrect output
|
||||||
|
|
||||||
|
TODO
|
319
docs/developing.md
Normal file
319
docs/developing.md
Normal file
|
@ -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
|
BIN
docs/fonts/Geist-Regular.ttf
Normal file
BIN
docs/fonts/Geist-Regular.ttf
Normal file
Binary file not shown.
BIN
docs/fonts/GeistMono-Regular.ttf
Normal file
BIN
docs/fonts/GeistMono-Regular.ttf
Normal file
Binary file not shown.
BIN
docs/fonts/GeistMonoVF.woff2
Normal file
BIN
docs/fonts/GeistMonoVF.woff2
Normal file
Binary file not shown.
BIN
docs/fonts/GeistVF.woff2
Normal file
BIN
docs/fonts/GeistVF.woff2
Normal file
Binary file not shown.
92
docs/fonts/LICENSE.txt
Normal file
92
docs/fonts/LICENSE.txt
Normal file
|
@ -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.
|
42
docs/index.md
Normal file
42
docs/index.md
Normal file
|
@ -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
|
113
docs/licences.md
Normal file
113
docs/licences.md
Normal file
|
@ -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 <https://creativecommons.org/publicdomain/zero/1.0/>
|
||||||
|
|
||||||
|
``` 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
|
59
docs/links.md
Normal file
59
docs/links.md
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
# backup links
|
||||||
|
|
||||||
|
for when first-party links like <https://surplus.joshwel.co> and <https://forge.joshwel.co> 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
|
||||||
|
```
|
58
docs/onwheels/bridges.md
Normal file
58
docs/onwheels/bridges.md
Normal file
|
@ -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/<bridge-name>/`, 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`.
|
43
docs/onwheels/emulating-termux-location.md
Normal file
43
docs/onwheels/emulating-termux-location.md
Normal file
|
@ -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 <https://wiki.termux.com/wiki/Termux-location> 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
|
46
docs/onwheels/emulating-termux-notification.md
Normal file
46
docs/onwheels/emulating-termux-notification.md
Normal file
|
@ -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 <https://wiki.termux.com/wiki/Termux-notification> for more information
|
329
docs/onwheels/index.md
Normal file
329
docs/onwheels/index.md
Normal file
|
@ -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<E>)
|
||||||
|
[lc:W sp:X sm:Y - Z]
|
||||||
|
|
||||||
|
!!! abstract "surplus on wheels has errored"
|
||||||
|
(A, B, C, D<E>)
|
||||||
|
[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?)
|
101
docs/onwheels/telegram-bridge.md
Normal file
101
docs/onwheels/telegram-bridge.md
Normal file
|
@ -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:<chat id>,...
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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).
|
210
docs/onwheels/whatsapp-bridge.md
Normal file
210
docs/onwheels/whatsapp-bridge.md
Normal file
|
@ -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:<chat id>,...
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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
|
||||||
|
`<ndk folder>/toolchains/llvm/prebuilt/<your platform>/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="<path to android ndk clang executable>" 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).
|
212
docs/stylesheets/extra.css
Normal file
212
docs/stylesheets/extra.css
Normal file
|
@ -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);
|
||||||
|
}
|
4
docs/stylesheets/pdf.scss
Normal file
4
docs/stylesheets/pdf.scss
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
@page {
|
||||||
|
size: A4;
|
||||||
|
margin: 1.25cm;
|
||||||
|
}
|
11
docs/using.md
Normal file
11
docs/using.md
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# the user's handbook
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## as a command line tool
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## as a python library
|
||||||
|
|
||||||
|
TODO
|
114
mkdocs.yml
Normal file
114
mkdocs.yml
Normal file
|
@ -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<br>
|
||||||
|
documentation is dedicated to the public domain with <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0</a>
|
||||||
|
|
||||||
|
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
|
23
src/tools/docs-prebuild.py
Normal file
23
src/tools/docs-prebuild.py
Normal file
|
@ -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)
|
Loading…
Reference in a new issue