libwatchduty 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- libwatchduty-0.1.0/.gitignore +81 -0
- libwatchduty-0.1.0/PKG-INFO +223 -0
- libwatchduty-0.1.0/README.md +207 -0
- libwatchduty-0.1.0/docs/screenshots/README.md +11 -0
- libwatchduty-0.1.0/pyproject.toml +45 -0
- libwatchduty-0.1.0/src/libwatchduty/__init__.py +9 -0
- libwatchduty-0.1.0/src/libwatchduty/__main__.py +5 -0
- libwatchduty-0.1.0/src/libwatchduty/aircraft.py +148 -0
- libwatchduty-0.1.0/src/libwatchduty/cli.py +1638 -0
- libwatchduty-0.1.0/src/libwatchduty/client.py +544 -0
- libwatchduty-0.1.0/src/libwatchduty/colors.py +99 -0
- libwatchduty-0.1.0/src/libwatchduty/geo_landmarks.py +193 -0
- libwatchduty-0.1.0/src/libwatchduty/images.py +198 -0
- libwatchduty-0.1.0/src/libwatchduty/install_mapscii.py +73 -0
- libwatchduty-0.1.0/src/libwatchduty/location.py +209 -0
- libwatchduty-0.1.0/src/libwatchduty/stills.py +184 -0
- libwatchduty-0.1.0/src/libwatchduty/tables.py +455 -0
- libwatchduty-0.1.0/src/libwatchduty/tui.py +4855 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/.bin/mapscii +1 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/.bin/pbf +1 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/.package-lock.json +258 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/point-geometry/.travis.yml +8 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/point-geometry/HISTORY.md +5 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/point-geometry/LICENSE +13 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/point-geometry/README.md +364 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/point-geometry/index.js +312 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/point-geometry/package.json +33 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/point-geometry/test.js +139 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/.eslintrc +3 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/.travis.yml +7 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/CHANGELOG.md +41 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/LICENSE.txt +28 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/README.md +104 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/fixtures.js +157 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/index.js +3 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/package.json +33 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/proto/vector_tile.proto +88 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/bench.js +36 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/12-1143-1497.vector.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/14-8801-5371.vector.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/lots-of-tags.vector.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/multi-line.pbf +4 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/multi-point.pbf +2 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/multi-polygon.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/multipolygon-with-closepath.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/multipolygon.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/polygon-with-inner.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/singleton-multi-line.pbf +3 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/singleton-multi-point.pbf +2 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/singleton-multi-polygon.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/stacked-multipolygon.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/zero-line.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/zero-point.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/fixtures/zero-polygon.pbf +0 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/@mapbox/vector-tile/test/parse.test.js +225 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/ansi-regex/index.d.ts +37 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/ansi-regex/index.js +10 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/ansi-regex/license +9 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/ansi-regex/package.json +55 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/ansi-regex/readme.md +78 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/LICENSE +21 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/README.md +57 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/changelog.md +1 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/browser/bluebird.core.js +3914 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/browser/bluebird.core.min.js +31 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/browser/bluebird.js +5778 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/browser/bluebird.min.js +31 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/any.js +21 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/assert.js +55 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/async.js +120 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/bind.js +67 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/bluebird.js +11 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/call_get.js +123 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/cancel.js +129 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/catch_filter.js +42 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/context.js +69 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/debuggability.js +1009 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/direct_resolve.js +46 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/each.js +30 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/errors.js +116 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/es5.js +80 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/filter.js +12 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/finally.js +146 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/generators.js +223 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/join.js +165 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/map.js +175 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/method.js +55 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/nodeback.js +51 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/nodeify.js +58 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/promise.js +819 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/promise_array.js +186 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/promisify.js +314 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/props.js +118 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/queue.js +73 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/race.js +49 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/reduce.js +183 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/schedule.js +62 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/settle.js +47 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/some.js +148 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/synchronous_inspection.js +103 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/thenables.js +86 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/timers.js +93 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/using.js +226 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/js/release/util.js +421 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bluebird/package.json +78 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bresenham/.npmignore +25 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bresenham/.travis.yml +7 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bresenham/LICENSE +21 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bresenham/README.md +44 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bresenham/example.js +3 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bresenham/generator.js +28 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bresenham/index.js +33 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bresenham/package.json +29 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/bresenham/test/index.js +64 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/earcut/LICENSE +15 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/earcut/README.md +255 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/earcut/package.json +43 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/earcut/src/earcut.js +681 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/emoji-regex/LICENSE-MIT.txt +20 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/emoji-regex/README.md +73 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/emoji-regex/es2015/index.js +6 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/emoji-regex/es2015/text.js +6 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/emoji-regex/index.d.ts +23 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/emoji-regex/index.js +6 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/emoji-regex/package.json +50 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/emoji-regex/text.js +6 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/ieee754/LICENSE +11 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/ieee754/README.md +51 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/ieee754/index.d.ts +10 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/ieee754/index.js +85 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/ieee754/package.json +52 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/is-fullwidth-code-point/index.d.ts +17 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/is-fullwidth-code-point/index.js +50 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/is-fullwidth-code-point/license +9 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/is-fullwidth-code-point/package.json +42 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/is-fullwidth-code-point/readme.md +39 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/keypress/README.md +101 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/keypress/index.js +408 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/keypress/package.json +20 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/keypress/test.js +28 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/.eslintrc.js +36 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/.github/ISSUE_TEMPLATE/BugReport.md +26 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/.github/ISSUE_TEMPLATE/FeatureRequest.md +22 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/.github/ISSUE_TEMPLATE/Question.md +14 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/.github/ISSUE_TEMPLATE/Support.md +15 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/.travis.yml +9 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/AUTHORS +7 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/LICENSE +22 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/README.md +144 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/bin/mapscii.sh +6 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/main.js +55 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/package.json +49 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/snap/snapcraft.yaml +19 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/BrailleBuffer.js +211 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/Canvas.js +202 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/LabelBuffer.js +57 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/Mapscii.js +322 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/Renderer.js +340 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/Styler.js +133 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/Tile.js +167 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/TileSource.js +177 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/TileSource.spec.js +12 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/config.js +52 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/utils.js +103 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/src/utils.spec.js +47 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/styles/bright.json +2191 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/mapscii/styles/dark.json +1560 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/node-fetch/LICENSE.md +22 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/node-fetch/README.md +634 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/node-fetch/browser.js +25 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/node-fetch/package.json +89 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/pbf/LICENSE +27 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/pbf/README.md +453 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/pbf/bin/pbf +19 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/pbf/compile.js +435 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/pbf/index.js +642 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/pbf/package.json +81 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/.travis.yml +7 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/LICENSE +21 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/README.md +122 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/example.js +11 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/example.proto +13 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/index.js +6 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/package.json +31 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/parse.js +769 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/stringify.js +206 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/basic.json +90 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/basic.proto +11 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/comments.json +99 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/comments.proto +19 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/complex.json +125 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/complex.proto +30 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/enum.json +42 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/enum.proto +8 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/escaped-quotes.json +32 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/escaped-quotes.proto +3 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/extend.json +167 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/extend.proto +19 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/import.json +30 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/import.proto +6 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/map.json +33 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/map.proto +3 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/no-tags.proto +8 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/oneof.json +41 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/oneof.proto +6 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/option.json +364 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/option.proto +72 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/options.json +47 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/options.proto +8 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/pheromon-trajectories.proto +8 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/reserved.json +55 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/reserved.proto +17 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/search.json +30 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/search.proto +5 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/service.json +108 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/service.proto +30 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/valid-packed.proto +35 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/version.json +90 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/fixtures/version.proto +13 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/test/index.js +157 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/protocol-buffers-schema/tokenize.js +56 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/quickselect/LICENSE +15 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/quickselect/README.md +28 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/quickselect/index.js +54 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/quickselect/package.json +43 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/quickselect/quickselect.js +63 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/rbush/LICENSE +21 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/rbush/README.md +218 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/rbush/index.js +512 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/rbush/package.json +56 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/rbush/rbush.js +574 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/rbush/rbush.min.js +1 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/resolve-protobuf-schema/.travis.yml +3 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/resolve-protobuf-schema/LICENSE +21 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/resolve-protobuf-schema/README.md +49 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/resolve-protobuf-schema/index.js +50 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/resolve-protobuf-schema/package.json +25 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/resolve-protobuf-schema/test/a.proto +5 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/resolve-protobuf-schema/test/b.proto +5 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/resolve-protobuf-schema/test/c.proto +3 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/resolve-protobuf-schema/test/index.js +49 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/simplify-js/LICENSE +22 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/simplify-js/README.md +19 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/simplify-js/index.d.ts +9 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/simplify-js/package.json +38 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/simplify-js/simplify.js +123 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/string-width/index.d.ts +29 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/string-width/index.js +47 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/string-width/license +9 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/string-width/package.json +56 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/string-width/readme.md +50 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/strip-ansi/index.d.ts +17 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/strip-ansi/index.js +4 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/strip-ansi/license +9 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/strip-ansi/package.json +54 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/strip-ansi/readme.md +46 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/term-mouse/History.md +5 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/term-mouse/LICENSE +20 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/term-mouse/README.md +54 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/term-mouse/index.js +204 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/term-mouse/package.json +10 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/term-mouse/test.js +12 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/tr46/.npmignore +4 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/tr46/index.js +193 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/tr46/package.json +31 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/userhome/LICENSE-MIT +22 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/userhome/README.md +27 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/userhome/index.js +14 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/userhome/package.json +35 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/userhome/test.js +19 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/webidl-conversions/LICENSE.md +12 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/webidl-conversions/README.md +53 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/webidl-conversions/package.json +23 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/whatwg-url/LICENSE.txt +21 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/whatwg-url/README.md +67 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/whatwg-url/package.json +32 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/x256/.travis.yml +6 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/x256/colors.json +256 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/x256/example/charm.js +5 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/x256/example/ix.js +3 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/x256/example/raw.js +3 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/x256/index.js +35 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/x256/package.json +53 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/x256/readme.markdown +83 -0
- libwatchduty-0.1.0/vendor/mapscii/node_modules/x256/test/id.js +36 -0
- libwatchduty-0.1.0/vendor/mapscii/package-lock.json +265 -0
- libwatchduty-0.1.0/vendor/mapscii/package.json +9 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
|
|
7
|
+
# Distribution / packaging
|
|
8
|
+
.Python
|
|
9
|
+
build/
|
|
10
|
+
develop-eggs/
|
|
11
|
+
dist/
|
|
12
|
+
downloads/
|
|
13
|
+
eggs/
|
|
14
|
+
.eggs/
|
|
15
|
+
lib/
|
|
16
|
+
lib64/
|
|
17
|
+
parts/
|
|
18
|
+
sdist/
|
|
19
|
+
var/
|
|
20
|
+
wheels/
|
|
21
|
+
*.egg-info/
|
|
22
|
+
.installed.cfg
|
|
23
|
+
*.egg
|
|
24
|
+
MANIFEST
|
|
25
|
+
|
|
26
|
+
# Virtual environments
|
|
27
|
+
.venv/
|
|
28
|
+
venv/
|
|
29
|
+
ENV/
|
|
30
|
+
env/
|
|
31
|
+
|
|
32
|
+
# Environment / secrets
|
|
33
|
+
.env
|
|
34
|
+
.env.*
|
|
35
|
+
!.env.example
|
|
36
|
+
|
|
37
|
+
# Test / coverage
|
|
38
|
+
.pytest_cache/
|
|
39
|
+
.coverage
|
|
40
|
+
.coverage.*
|
|
41
|
+
htmlcov/
|
|
42
|
+
.tox/
|
|
43
|
+
.nox/
|
|
44
|
+
.cache
|
|
45
|
+
nosetests.xml
|
|
46
|
+
coverage.xml
|
|
47
|
+
*.cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
|
|
50
|
+
# Type checkers / linters
|
|
51
|
+
.mypy_cache/
|
|
52
|
+
.dmypy.json
|
|
53
|
+
.pyre/
|
|
54
|
+
.ruff_cache/
|
|
55
|
+
|
|
56
|
+
# IDE / editor
|
|
57
|
+
.idea/
|
|
58
|
+
.vscode/
|
|
59
|
+
*.swp
|
|
60
|
+
*.swo
|
|
61
|
+
.DS_Store
|
|
62
|
+
|
|
63
|
+
# Project-specific: HAR captures & API probes (may contain tokens, PII, coords)
|
|
64
|
+
*.har
|
|
65
|
+
watchduty*.json
|
|
66
|
+
probe_*.py
|
|
67
|
+
|
|
68
|
+
# Local scratch / private working data (HARs, dumps, etc.)
|
|
69
|
+
.local/
|
|
70
|
+
|
|
71
|
+
# Docs build artifacts
|
|
72
|
+
docs/screenshots/png/
|
|
73
|
+
docs/_build/
|
|
74
|
+
|
|
75
|
+
# Vendor bundle: ship node_modules but ignore caches/logs inside it
|
|
76
|
+
vendor/mapscii/node_modules/.cache/
|
|
77
|
+
vendor/**/node_modules/.cache/
|
|
78
|
+
vendor/**/*.log
|
|
79
|
+
npm-debug.log*
|
|
80
|
+
yarn-debug.log*
|
|
81
|
+
yarn-error.log*
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: libwatchduty
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unofficial Python client for app.watchduty.org fire/incident data
|
|
5
|
+
Author: Max
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Requires-Dist: requests>=2.31
|
|
9
|
+
Requires-Dist: tqdm>=4.65
|
|
10
|
+
Provides-Extra: test
|
|
11
|
+
Requires-Dist: pyte>=0.8; extra == 'test'
|
|
12
|
+
Requires-Dist: pytest>=7; extra == 'test'
|
|
13
|
+
Provides-Extra: tui
|
|
14
|
+
Requires-Dist: pyte>=0.8; extra == 'tui'
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# libwatchduty
|
|
18
|
+
|
|
19
|
+
> Unofficial Watch Duty wildfire dashboard — Python client for `api.watchduty.org` plus a threat-ranked terminal UI.
|
|
20
|
+
|
|
21
|
+
Reverse-engineered from the [app.watchduty.org](https://app.watchduty.org) browser app. **No affiliation with Watch Duty.** Read endpoints are public; user-scoped endpoints (saved places, profile) require login.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Screenshot
|
|
26
|
+
|
|
27
|
+
Rendered against a seeded fixture state at 40×160. Full set under [`docs/screenshots/`](docs/screenshots/) (24×100, 40×160, 60×200 — one per detail tab).
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
◉ watchduty │ filters wildfire,location,flooding,hazard │ ⌖ 37.77,-122.42 ≤500km (fixture) │ sort ▼ THREAT │ 4 of 5 │ refresh
|
|
31
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
32
|
+
THREAT D INCIDENT │#104994
|
|
33
|
+
DIST SIZE CONTAINMENT │▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
|
|
34
|
+
────────────────────────────────────────────────────────────────│ PINE RIDGE FIRE ↗
|
|
35
|
+
▰▰▰ ↗ #104994 Pine Ridge Fire [active] │ updates radio map evac
|
|
36
|
+
12.4km 3,400 ac 28% ▰▰▱ │ · 14:02 IC: structure threat lifted east flank
|
|
37
|
+
▰▰▱ ← #105110 Cedar Hollow Fire [active] │ · 13:41 CalFire: 28% containment, growth slowing
|
|
38
|
+
61.0km 980 ac 45% ▰▱▱ │ · 12:55 evacuations expanded zone HUM-7B
|
|
39
|
+
▰▱▱ ↑ #105316 Box Canyon Fire [active] │
|
|
40
|
+
88.2km 140 ac 80% ▱▱▱ │
|
|
41
|
+
▱▱▱ · #105410 Mariposa Prescribed Burn [planned] │
|
|
42
|
+
24.9km 50 ac -- │
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
> The screenshots are real ANSI dumps captured under `pyte`; if you want the exact escape-sequence colored versions used in the original capture, see [`docs/screenshots/ansi/`](docs/screenshots/ansi/).
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- **Threat scoring** — composite per-fire score combining proximity, size, containment, growth rate, and wind speed/bearing; visible as a 3-segment `▰▱` bar in the list.
|
|
52
|
+
- **Live updates polling** — background worker thread re-fetches geo events and reports on a configurable interval (`--refresh`), with toast notifications when new reports arrive.
|
|
53
|
+
- **Radio embed** — Broadcastify scanner feeds for the county the selected fire sits in, online feeds grouped first, listener counts inline.
|
|
54
|
+
- **Inline cameras** — wildfire-detection camera stills rendered in-terminal on kitty / ghostty / iTerm2 (Kitty graphics protocol), with size and on/off toggles.
|
|
55
|
+
- **Embedded mapscii** — the Map tab embeds [mapscii](https://github.com/rastapasta/mapscii) inside the right pane via a pyte-backed PTY; full-screen handoff on `m`.
|
|
56
|
+
- **Compact list mode** — toggle between two-line "card" rows and a single-line dense view (`z`).
|
|
57
|
+
- **Threat-ranked sort** — default sort by threat when `--near` is set; cycles through threat / distance / acreage / updated (`t`, reverse with `T`).
|
|
58
|
+
- **Filter + search** — incremental `/`-filter across name/type, `n`/`N` to jump matches, `X` to clear.
|
|
59
|
+
- **Pure-Python deps** — `requests` + `tqdm` for the core; `pyte` only when the inline mapscii embed is wanted.
|
|
60
|
+
- **CLI for scripting** — `watchduty fires`, `event`, `reports`, `bundle`, `radio`, `cameras`, `stills`, `aircraft` — every list subcommand has `--json` for piping.
|
|
61
|
+
- **Auto-locate** — `--near auto` resolves to your approximate latitude/longitude via IP geolocation; otherwise pass `LAT,LNG`.
|
|
62
|
+
- **Camera still capture** — one-shot `stills capture` or a recurring `stills watch` timelapse loop.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Install
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install libwatchduty # CLI + client
|
|
70
|
+
pip install libwatchduty[tui] # inline mapscii embed (pyte)\
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Python ≥ 3.9. The `tui` extra only adds [`pyte`](https://pypi.org/project/pyte/) for the embedded map — the dashboard itself runs without it (you get full-screen mapscii via `m` instead).
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Quick start
|
|
78
|
+
|
|
79
|
+
> The full walkthrough — install, first launch, keybindings cheat-sheet,
|
|
80
|
+
> `:` commands, scripting against the API — lives in
|
|
81
|
+
> **[`docs/QUICKSTART.md`](docs/QUICKSTART.md)**.
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install libwatchduty[tui]
|
|
85
|
+
|
|
86
|
+
watchduty tui --near auto --within 250 --refresh 60
|
|
87
|
+
watchduty fires --active
|
|
88
|
+
watchduty event 105316
|
|
89
|
+
watchduty reports 105316
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Bare `watchduty` (no subcommand) launches the TUI with sensible defaults — `--near auto --within 250 --refresh 60`. Set `WATCHDUTY_HOME=37.77,-122.42` (or `auto`) to skip the flag.
|
|
93
|
+
|
|
94
|
+
Python client:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from libwatchduty import WatchDutyClient
|
|
98
|
+
|
|
99
|
+
c = WatchDutyClient()
|
|
100
|
+
for ev in c.list_geo_events(types=["wildfire"]):
|
|
101
|
+
if ev["is_active"]:
|
|
102
|
+
print(ev["id"], ev["name"], ev["data"].get("acreage"), "ac")
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## TUI keybindings
|
|
108
|
+
|
|
109
|
+
Read off the live source in [`src/libwatchduty/tui.py`](src/libwatchduty/tui.py). Focus-aware bindings depend on whether the **list** (left) or **detail** (right) pane is active.
|
|
110
|
+
|
|
111
|
+
### Navigation
|
|
112
|
+
|
|
113
|
+
| Key | Action |
|
|
114
|
+
|---|---|
|
|
115
|
+
| `j` / `↓` | Move selection down (list focus) **or** scroll detail one line (detail focus) |
|
|
116
|
+
| `k` / `↑` | Move selection up (list focus) **or** scroll detail up one line (detail focus) |
|
|
117
|
+
| `J` | Scroll detail pane down (always, regardless of focus) |
|
|
118
|
+
| `K` | Scroll detail pane up (always, regardless of focus) |
|
|
119
|
+
| `PgDn` | Scroll detail pane one page down |
|
|
120
|
+
| `PgUp` | Scroll detail pane one page up |
|
|
121
|
+
| `g g` | Jump to first fire (chord) |
|
|
122
|
+
| `G` | Jump to last fire |
|
|
123
|
+
| `Ctrl-D` | Half-page down (selection) |
|
|
124
|
+
| `Ctrl-U` | Half-page up (selection) |
|
|
125
|
+
| `h` | Focus list pane |
|
|
126
|
+
| `l` | Focus detail pane (loads reports for selected fire) |
|
|
127
|
+
| `←` | Previous detail tab; double-tap returns focus to list |
|
|
128
|
+
| `→` | Next detail tab |
|
|
129
|
+
| `Tab` | Cycle focus (list ↔ detail) — within detail, cycles tabs |
|
|
130
|
+
| `Shift-Tab` | Reverse tab cycle within detail |
|
|
131
|
+
| `Enter` | Open selected fire in detail pane |
|
|
132
|
+
| `Esc` / `Backspace` | Return focus to list |
|
|
133
|
+
|
|
134
|
+
### Detail tabs
|
|
135
|
+
|
|
136
|
+
| Key | Tab |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `1` / `u` | Updates (reports feed) |
|
|
139
|
+
| `2` / `R` | Radio (Broadcastify scanner feeds) |
|
|
140
|
+
| `3` / `c` | Map (embedded mapscii) |
|
|
141
|
+
| `4` / `e` | Evac (evacuation zones) |
|
|
142
|
+
|
|
143
|
+
### Map & image controls
|
|
144
|
+
|
|
145
|
+
| Key | Action |
|
|
146
|
+
|---|---|
|
|
147
|
+
| `m` | Launch fullscreen mapscii at the selected fire |
|
|
148
|
+
| `+` / `=` | Zoom mapscii in (when map active) **or** bump inline-image size |
|
|
149
|
+
| `-` / `_` | Zoom mapscii out (when map active) **or** shrink inline-image size |
|
|
150
|
+
| `i` / `F` | Open selected fire's header image fullscreen (kitty/ghostty/iTerm2 only) |
|
|
151
|
+
| `p` | Toggle inline header camera image |
|
|
152
|
+
|
|
153
|
+
### Filters, sort, refresh
|
|
154
|
+
|
|
155
|
+
| Key | Action |
|
|
156
|
+
|---|---|
|
|
157
|
+
| `/` | Open incremental name/type filter |
|
|
158
|
+
| `X` / `Ctrl-L` | Clear filter |
|
|
159
|
+
| `n` | Jump to next match |
|
|
160
|
+
| `N` | Jump to previous match |
|
|
161
|
+
| `:` | Open command prompt |
|
|
162
|
+
| `t` | Cycle sort key (threat → distance → acreage → updated) |
|
|
163
|
+
| `T` | Reverse sort direction |
|
|
164
|
+
| `[` | Shrink `--within` radius by 50 km |
|
|
165
|
+
| `]` | Grow `--within` radius by 50 km |
|
|
166
|
+
| `r` | Force refresh of fires + reports for selected event |
|
|
167
|
+
| `L` | Toggle LIVE mode (faster polling of reports for selected fire) |
|
|
168
|
+
| `z` | Toggle compact list (one line per fire vs. two-line card) |
|
|
169
|
+
| `?` | Help overlay |
|
|
170
|
+
| `q` | Quit |
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Threat scoring
|
|
175
|
+
|
|
176
|
+
Each fire gets a composite `[0, 100]` score that drives the default sort and the colored `▰▱` bar. The formula multiplies normalized factors so any near-zero input collapses the score (a 100k-acre fire at 600 km still scores low):
|
|
177
|
+
|
|
178
|
+
> **score = clamp(100 · proximity · (0.4 + 0.6·size) · uncontained · growth · wind · bearing, 0, 100)**
|
|
179
|
+
|
|
180
|
+
where `proximity = 1 − dist/within_km` (clamped to `[0,1]`), `size = log10(1+acres) / log10(1+1000)`, `uncontained = 1 − containment/100`, `growth = 1 + 0.5·growth_rate` (acreage delta over the rolling history window), `wind = 1 + 0.04·wind_mph`, and `bearing` scales `[0.5, 1.5]` based on how directly the wind blows from the fire toward you. Prescribed/planned burns are capped at 5. Tiers: `≥60` red, `≥20` amber, `<6` dim, else green.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## mapscii setup
|
|
185
|
+
|
|
186
|
+
The Map tab embeds [mapscii](https://github.com/rastapasta/mapscii) (an ASCII-art world map client). A pinned, working checkout is bundled under [`vendor/mapscii/`](vendor/mapscii/) and ships as wheel data — the TUI prefers `vendor/mapscii/node_modules/.bin/mapscii` over anything in `$PATH`.
|
|
187
|
+
|
|
188
|
+
If the bundled copy isn't usable (e.g. you installed from sdist without Node, or `node_modules` is missing), drop to the fallback installer:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
watchduty-install-mapscii
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
This pulls and builds mapscii in a user-writable cache directory. Without mapscii at all, the Map tab degrades gracefully — you can still see the fire's lat/lng and jump to fullscreen rendering (`m`).
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Architecture
|
|
199
|
+
|
|
200
|
+
`client.py` owns the typed HTTP surface against `api.watchduty.org` (sessioned `requests`, paginated `iter_*` helpers, optional DRF token auth). The TUI's `run()` spins up a single background **worker thread** that drains a `queue.Queue` of typed request tuples (`REFRESH_FIRES`, `LOAD_REPORTS`, `LOAD_IMAGE`, …) and posts results onto an output queue. The main curses loop owns a `_TuiState` dataclass (fires list, reports cache, threat scores, focus + scroll positions, filter/sort state) — every keypress mutates `_TuiState`, every drained worker result mutates `_TuiState`, and the curses view is a pure render of that state. Result: input stays responsive while API calls run, with no async/asyncio anywhere.
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Testing
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
pip install .[test,tui]
|
|
208
|
+
pytest tests/
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Tests use `pyte` to render the TUI inside a fake PTY and assert on the resulting frame, plus straight unit tests over `client.py` against canned fixtures.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Contributing
|
|
216
|
+
|
|
217
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for the development setup, lint/test loop, and how to regenerate screenshots. Release notes live in [CHANGELOG.md](CHANGELOG.md).
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## License
|
|
222
|
+
|
|
223
|
+
MIT. See [LICENSE](LICENSE) if present; otherwise the `license = { text = "MIT" }` declaration in [`pyproject.toml`](pyproject.toml) is authoritative.
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# libwatchduty
|
|
2
|
+
|
|
3
|
+
> Unofficial Watch Duty wildfire dashboard — Python client for `api.watchduty.org` plus a threat-ranked terminal UI.
|
|
4
|
+
|
|
5
|
+
Reverse-engineered from the [app.watchduty.org](https://app.watchduty.org) browser app. **No affiliation with Watch Duty.** Read endpoints are public; user-scoped endpoints (saved places, profile) require login.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Screenshot
|
|
10
|
+
|
|
11
|
+
Rendered against a seeded fixture state at 40×160. Full set under [`docs/screenshots/`](docs/screenshots/) (24×100, 40×160, 60×200 — one per detail tab).
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
◉ watchduty │ filters wildfire,location,flooding,hazard │ ⌖ 37.77,-122.42 ≤500km (fixture) │ sort ▼ THREAT │ 4 of 5 │ refresh
|
|
15
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
16
|
+
THREAT D INCIDENT │#104994
|
|
17
|
+
DIST SIZE CONTAINMENT │▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
|
|
18
|
+
────────────────────────────────────────────────────────────────│ PINE RIDGE FIRE ↗
|
|
19
|
+
▰▰▰ ↗ #104994 Pine Ridge Fire [active] │ updates radio map evac
|
|
20
|
+
12.4km 3,400 ac 28% ▰▰▱ │ · 14:02 IC: structure threat lifted east flank
|
|
21
|
+
▰▰▱ ← #105110 Cedar Hollow Fire [active] │ · 13:41 CalFire: 28% containment, growth slowing
|
|
22
|
+
61.0km 980 ac 45% ▰▱▱ │ · 12:55 evacuations expanded zone HUM-7B
|
|
23
|
+
▰▱▱ ↑ #105316 Box Canyon Fire [active] │
|
|
24
|
+
88.2km 140 ac 80% ▱▱▱ │
|
|
25
|
+
▱▱▱ · #105410 Mariposa Prescribed Burn [planned] │
|
|
26
|
+
24.9km 50 ac -- │
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
> The screenshots are real ANSI dumps captured under `pyte`; if you want the exact escape-sequence colored versions used in the original capture, see [`docs/screenshots/ansi/`](docs/screenshots/ansi/).
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
- **Threat scoring** — composite per-fire score combining proximity, size, containment, growth rate, and wind speed/bearing; visible as a 3-segment `▰▱` bar in the list.
|
|
36
|
+
- **Live updates polling** — background worker thread re-fetches geo events and reports on a configurable interval (`--refresh`), with toast notifications when new reports arrive.
|
|
37
|
+
- **Radio embed** — Broadcastify scanner feeds for the county the selected fire sits in, online feeds grouped first, listener counts inline.
|
|
38
|
+
- **Inline cameras** — wildfire-detection camera stills rendered in-terminal on kitty / ghostty / iTerm2 (Kitty graphics protocol), with size and on/off toggles.
|
|
39
|
+
- **Embedded mapscii** — the Map tab embeds [mapscii](https://github.com/rastapasta/mapscii) inside the right pane via a pyte-backed PTY; full-screen handoff on `m`.
|
|
40
|
+
- **Compact list mode** — toggle between two-line "card" rows and a single-line dense view (`z`).
|
|
41
|
+
- **Threat-ranked sort** — default sort by threat when `--near` is set; cycles through threat / distance / acreage / updated (`t`, reverse with `T`).
|
|
42
|
+
- **Filter + search** — incremental `/`-filter across name/type, `n`/`N` to jump matches, `X` to clear.
|
|
43
|
+
- **Pure-Python deps** — `requests` + `tqdm` for the core; `pyte` only when the inline mapscii embed is wanted.
|
|
44
|
+
- **CLI for scripting** — `watchduty fires`, `event`, `reports`, `bundle`, `radio`, `cameras`, `stills`, `aircraft` — every list subcommand has `--json` for piping.
|
|
45
|
+
- **Auto-locate** — `--near auto` resolves to your approximate latitude/longitude via IP geolocation; otherwise pass `LAT,LNG`.
|
|
46
|
+
- **Camera still capture** — one-shot `stills capture` or a recurring `stills watch` timelapse loop.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Install
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install libwatchduty # CLI + client
|
|
54
|
+
pip install libwatchduty[tui] # inline mapscii embed (pyte)\
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Python ≥ 3.9. The `tui` extra only adds [`pyte`](https://pypi.org/project/pyte/) for the embedded map — the dashboard itself runs without it (you get full-screen mapscii via `m` instead).
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Quick start
|
|
62
|
+
|
|
63
|
+
> The full walkthrough — install, first launch, keybindings cheat-sheet,
|
|
64
|
+
> `:` commands, scripting against the API — lives in
|
|
65
|
+
> **[`docs/QUICKSTART.md`](docs/QUICKSTART.md)**.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install libwatchduty[tui]
|
|
69
|
+
|
|
70
|
+
watchduty tui --near auto --within 250 --refresh 60
|
|
71
|
+
watchduty fires --active
|
|
72
|
+
watchduty event 105316
|
|
73
|
+
watchduty reports 105316
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Bare `watchduty` (no subcommand) launches the TUI with sensible defaults — `--near auto --within 250 --refresh 60`. Set `WATCHDUTY_HOME=37.77,-122.42` (or `auto`) to skip the flag.
|
|
77
|
+
|
|
78
|
+
Python client:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from libwatchduty import WatchDutyClient
|
|
82
|
+
|
|
83
|
+
c = WatchDutyClient()
|
|
84
|
+
for ev in c.list_geo_events(types=["wildfire"]):
|
|
85
|
+
if ev["is_active"]:
|
|
86
|
+
print(ev["id"], ev["name"], ev["data"].get("acreage"), "ac")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## TUI keybindings
|
|
92
|
+
|
|
93
|
+
Read off the live source in [`src/libwatchduty/tui.py`](src/libwatchduty/tui.py). Focus-aware bindings depend on whether the **list** (left) or **detail** (right) pane is active.
|
|
94
|
+
|
|
95
|
+
### Navigation
|
|
96
|
+
|
|
97
|
+
| Key | Action |
|
|
98
|
+
|---|---|
|
|
99
|
+
| `j` / `↓` | Move selection down (list focus) **or** scroll detail one line (detail focus) |
|
|
100
|
+
| `k` / `↑` | Move selection up (list focus) **or** scroll detail up one line (detail focus) |
|
|
101
|
+
| `J` | Scroll detail pane down (always, regardless of focus) |
|
|
102
|
+
| `K` | Scroll detail pane up (always, regardless of focus) |
|
|
103
|
+
| `PgDn` | Scroll detail pane one page down |
|
|
104
|
+
| `PgUp` | Scroll detail pane one page up |
|
|
105
|
+
| `g g` | Jump to first fire (chord) |
|
|
106
|
+
| `G` | Jump to last fire |
|
|
107
|
+
| `Ctrl-D` | Half-page down (selection) |
|
|
108
|
+
| `Ctrl-U` | Half-page up (selection) |
|
|
109
|
+
| `h` | Focus list pane |
|
|
110
|
+
| `l` | Focus detail pane (loads reports for selected fire) |
|
|
111
|
+
| `←` | Previous detail tab; double-tap returns focus to list |
|
|
112
|
+
| `→` | Next detail tab |
|
|
113
|
+
| `Tab` | Cycle focus (list ↔ detail) — within detail, cycles tabs |
|
|
114
|
+
| `Shift-Tab` | Reverse tab cycle within detail |
|
|
115
|
+
| `Enter` | Open selected fire in detail pane |
|
|
116
|
+
| `Esc` / `Backspace` | Return focus to list |
|
|
117
|
+
|
|
118
|
+
### Detail tabs
|
|
119
|
+
|
|
120
|
+
| Key | Tab |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `1` / `u` | Updates (reports feed) |
|
|
123
|
+
| `2` / `R` | Radio (Broadcastify scanner feeds) |
|
|
124
|
+
| `3` / `c` | Map (embedded mapscii) |
|
|
125
|
+
| `4` / `e` | Evac (evacuation zones) |
|
|
126
|
+
|
|
127
|
+
### Map & image controls
|
|
128
|
+
|
|
129
|
+
| Key | Action |
|
|
130
|
+
|---|---|
|
|
131
|
+
| `m` | Launch fullscreen mapscii at the selected fire |
|
|
132
|
+
| `+` / `=` | Zoom mapscii in (when map active) **or** bump inline-image size |
|
|
133
|
+
| `-` / `_` | Zoom mapscii out (when map active) **or** shrink inline-image size |
|
|
134
|
+
| `i` / `F` | Open selected fire's header image fullscreen (kitty/ghostty/iTerm2 only) |
|
|
135
|
+
| `p` | Toggle inline header camera image |
|
|
136
|
+
|
|
137
|
+
### Filters, sort, refresh
|
|
138
|
+
|
|
139
|
+
| Key | Action |
|
|
140
|
+
|---|---|
|
|
141
|
+
| `/` | Open incremental name/type filter |
|
|
142
|
+
| `X` / `Ctrl-L` | Clear filter |
|
|
143
|
+
| `n` | Jump to next match |
|
|
144
|
+
| `N` | Jump to previous match |
|
|
145
|
+
| `:` | Open command prompt |
|
|
146
|
+
| `t` | Cycle sort key (threat → distance → acreage → updated) |
|
|
147
|
+
| `T` | Reverse sort direction |
|
|
148
|
+
| `[` | Shrink `--within` radius by 50 km |
|
|
149
|
+
| `]` | Grow `--within` radius by 50 km |
|
|
150
|
+
| `r` | Force refresh of fires + reports for selected event |
|
|
151
|
+
| `L` | Toggle LIVE mode (faster polling of reports for selected fire) |
|
|
152
|
+
| `z` | Toggle compact list (one line per fire vs. two-line card) |
|
|
153
|
+
| `?` | Help overlay |
|
|
154
|
+
| `q` | Quit |
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Threat scoring
|
|
159
|
+
|
|
160
|
+
Each fire gets a composite `[0, 100]` score that drives the default sort and the colored `▰▱` bar. The formula multiplies normalized factors so any near-zero input collapses the score (a 100k-acre fire at 600 km still scores low):
|
|
161
|
+
|
|
162
|
+
> **score = clamp(100 · proximity · (0.4 + 0.6·size) · uncontained · growth · wind · bearing, 0, 100)**
|
|
163
|
+
|
|
164
|
+
where `proximity = 1 − dist/within_km` (clamped to `[0,1]`), `size = log10(1+acres) / log10(1+1000)`, `uncontained = 1 − containment/100`, `growth = 1 + 0.5·growth_rate` (acreage delta over the rolling history window), `wind = 1 + 0.04·wind_mph`, and `bearing` scales `[0.5, 1.5]` based on how directly the wind blows from the fire toward you. Prescribed/planned burns are capped at 5. Tiers: `≥60` red, `≥20` amber, `<6` dim, else green.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## mapscii setup
|
|
169
|
+
|
|
170
|
+
The Map tab embeds [mapscii](https://github.com/rastapasta/mapscii) (an ASCII-art world map client). A pinned, working checkout is bundled under [`vendor/mapscii/`](vendor/mapscii/) and ships as wheel data — the TUI prefers `vendor/mapscii/node_modules/.bin/mapscii` over anything in `$PATH`.
|
|
171
|
+
|
|
172
|
+
If the bundled copy isn't usable (e.g. you installed from sdist without Node, or `node_modules` is missing), drop to the fallback installer:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
watchduty-install-mapscii
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
This pulls and builds mapscii in a user-writable cache directory. Without mapscii at all, the Map tab degrades gracefully — you can still see the fire's lat/lng and jump to fullscreen rendering (`m`).
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Architecture
|
|
183
|
+
|
|
184
|
+
`client.py` owns the typed HTTP surface against `api.watchduty.org` (sessioned `requests`, paginated `iter_*` helpers, optional DRF token auth). The TUI's `run()` spins up a single background **worker thread** that drains a `queue.Queue` of typed request tuples (`REFRESH_FIRES`, `LOAD_REPORTS`, `LOAD_IMAGE`, …) and posts results onto an output queue. The main curses loop owns a `_TuiState` dataclass (fires list, reports cache, threat scores, focus + scroll positions, filter/sort state) — every keypress mutates `_TuiState`, every drained worker result mutates `_TuiState`, and the curses view is a pure render of that state. Result: input stays responsive while API calls run, with no async/asyncio anywhere.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Testing
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
pip install .[test,tui]
|
|
192
|
+
pytest tests/
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Tests use `pyte` to render the TUI inside a fake PTY and assert on the resulting frame, plus straight unit tests over `client.py` against canned fixtures.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Contributing
|
|
200
|
+
|
|
201
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for the development setup, lint/test loop, and how to regenerate screenshots. Release notes live in [CHANGELOG.md](CHANGELOG.md).
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
MIT. See [LICENSE](LICENSE) if present; otherwise the `license = { text = "MIT" }` declaration in [`pyproject.toml`](pyproject.toml) is authoritative.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# TUI screenshots
|
|
2
|
+
|
|
3
|
+
Reproducible screenshots of the `watchduty` TUI rendered in-process against a
|
|
4
|
+
synthetic, seeded `_TuiState` (no live API). Generated by
|
|
5
|
+
`scripts/capture_screenshots.py`, which forks a child under a PTY at each of
|
|
6
|
+
three predefined sizes (24x100, 40x160, 60x200), calls the `_draw_header` /
|
|
7
|
+
`_draw_list` / `_draw_detail` / `_draw_footer` functions once per detail tab
|
|
8
|
+
(updates, radio, map, evac), captures the resulting frame with `pyte`, and
|
|
9
|
+
writes a colored ANSI dump under `ansi/` plus an optional PNG under `png/`
|
|
10
|
+
(needs Pillow; skipped with a warning otherwise). To regenerate, run
|
|
11
|
+
`python -m scripts.capture_screenshots` from the repo root.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "libwatchduty"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Unofficial Python client for app.watchduty.org fire/incident data"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Max" }]
|
|
13
|
+
dependencies = ["requests>=2.31", "tqdm>=4.65"]
|
|
14
|
+
|
|
15
|
+
[project.optional-dependencies]
|
|
16
|
+
# Pure-Python VT100 emulator used by the TUI to embed mapscii inside the
|
|
17
|
+
# Map-tab rectangle. The dashboard still runs without it (mapscii falls
|
|
18
|
+
# back to fullscreen via `m`); install if you want the inline map.
|
|
19
|
+
tui = ["pyte>=0.8"]
|
|
20
|
+
test = ["pytest>=7", "pyte>=0.8"]
|
|
21
|
+
|
|
22
|
+
[project.scripts]
|
|
23
|
+
watchduty = "libwatchduty.cli:main"
|
|
24
|
+
watchduty-install-mapscii = "libwatchduty.install_mapscii:main"
|
|
25
|
+
|
|
26
|
+
[tool.pytest.ini_options]
|
|
27
|
+
testpaths = ["tests"]
|
|
28
|
+
addopts = "-ra"
|
|
29
|
+
|
|
30
|
+
[tool.hatch.build.targets.wheel]
|
|
31
|
+
packages = ["src/libwatchduty"]
|
|
32
|
+
|
|
33
|
+
# Ship the in-repo mapscii checkout (Node app, ~3 MB) as wheel data so
|
|
34
|
+
# the bundled binary is available after `pip install`. The TUI prefers
|
|
35
|
+
# vendor/mapscii/node_modules/.bin/mapscii before falling back to $PATH.
|
|
36
|
+
[tool.hatch.build.targets.wheel.shared-data]
|
|
37
|
+
"vendor/mapscii" = "share/libwatchduty/vendor/mapscii"
|
|
38
|
+
|
|
39
|
+
[tool.hatch.build.targets.sdist]
|
|
40
|
+
include = [
|
|
41
|
+
"src",
|
|
42
|
+
"vendor",
|
|
43
|
+
"README.md",
|
|
44
|
+
"pyproject.toml",
|
|
45
|
+
]
|