absolutely destroy this beautiful static html file by converting it to a slightly more dynamic flask app + docker container
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
This commit is contained in:
parent
95037c0f82
commit
af0eb90e42
@ -1,7 +1,27 @@
|
||||
pipeline:
|
||||
deploy:
|
||||
image: alpine:3.13
|
||||
build:
|
||||
image: plugins/docker
|
||||
volumes:
|
||||
- /var/web/live/:/deploy
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
settings:
|
||||
registry: gitea.malloc.hackerbots.net
|
||||
repo: gitea.malloc.hackerbots.net/tdfischer/hackerbots-live
|
||||
daemon_off: true
|
||||
auto_tag: true
|
||||
username:
|
||||
from_secret: GITEA_USERNAME
|
||||
password:
|
||||
from_secret: GITEA_PASSWORD
|
||||
deploy:
|
||||
image: docker
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
commands:
|
||||
- cp index.html /deploy
|
||||
- docker pull gitea.malloc.hackerbots.net/tdfischer/hackerbots-live:latest
|
||||
- mkdir -p ~/.ssh/
|
||||
- echo "$DEPLOY_SSH_KEY" > ~/.ssh/id_rsa
|
||||
- chmod a-rwx,u+r ~/.ssh/id_rsa
|
||||
- chmod a-rwx,u+rx ~/.ssh/
|
||||
- ssh -o StrictHostKeyChecking=no hackerbots-live-deploy@hackerbots.net sudo systemctl restart hackerbots-live
|
||||
- rm ~/.ssh/id_rsa
|
||||
secrets: [deploy_ssh_key]
|
||||
|
10
Dockerfile
Normal file
10
Dockerfile
Normal file
@ -0,0 +1,10 @@
|
||||
FROM python:3.9-alpine
|
||||
|
||||
RUN pip install pipenv && pip install gunicorn==20.1.0 eventlet==0.30.2
|
||||
|
||||
WORKDIR /app
|
||||
COPY . /app
|
||||
|
||||
RUN pipenv install --system
|
||||
|
||||
CMD ["gunicorn", "-k", "eventlet", "-w", "1", "-b", "0.0.0.0:5000", "app:app"]
|
15
Pipfile
Normal file
15
Pipfile
Normal file
@ -0,0 +1,15 @@
|
||||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[packages]
|
||||
flask = "*"
|
||||
flask-json = "*"
|
||||
requests = "*"
|
||||
flask-socketio = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.9"
|
286
Pipfile.lock
generated
Normal file
286
Pipfile.lock
generated
Normal file
@ -0,0 +1,286 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "f400616d4ffcdf3f29915b354836ec80e531bd6c311b067fc3ebf773c77a85eb"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.9"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"bidict": {
|
||||
"hashes": [
|
||||
"sha256:1e0f7f74e4860e6d0943a05d4134c63a2fad86f3d4732fb265bd79e4e856d81d",
|
||||
"sha256:6ef212238eb884b664f28da76f33f1d28b260f665fc737b413b287d5487d1e7b"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.0'",
|
||||
"version": "==0.22.1"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3",
|
||||
"sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2022.12.7"
|
||||
},
|
||||
"charset-normalizer": {
|
||||
"hashes": [
|
||||
"sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6",
|
||||
"sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1",
|
||||
"sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e",
|
||||
"sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373",
|
||||
"sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62",
|
||||
"sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230",
|
||||
"sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be",
|
||||
"sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c",
|
||||
"sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0",
|
||||
"sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448",
|
||||
"sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f",
|
||||
"sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649",
|
||||
"sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d",
|
||||
"sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0",
|
||||
"sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706",
|
||||
"sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a",
|
||||
"sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59",
|
||||
"sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23",
|
||||
"sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5",
|
||||
"sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb",
|
||||
"sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e",
|
||||
"sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e",
|
||||
"sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c",
|
||||
"sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28",
|
||||
"sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d",
|
||||
"sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41",
|
||||
"sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974",
|
||||
"sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce",
|
||||
"sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f",
|
||||
"sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1",
|
||||
"sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d",
|
||||
"sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8",
|
||||
"sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017",
|
||||
"sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31",
|
||||
"sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7",
|
||||
"sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8",
|
||||
"sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e",
|
||||
"sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14",
|
||||
"sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd",
|
||||
"sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d",
|
||||
"sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795",
|
||||
"sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b",
|
||||
"sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b",
|
||||
"sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b",
|
||||
"sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203",
|
||||
"sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f",
|
||||
"sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19",
|
||||
"sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1",
|
||||
"sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a",
|
||||
"sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac",
|
||||
"sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9",
|
||||
"sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0",
|
||||
"sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137",
|
||||
"sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f",
|
||||
"sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6",
|
||||
"sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5",
|
||||
"sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909",
|
||||
"sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f",
|
||||
"sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0",
|
||||
"sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324",
|
||||
"sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755",
|
||||
"sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb",
|
||||
"sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854",
|
||||
"sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c",
|
||||
"sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60",
|
||||
"sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84",
|
||||
"sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0",
|
||||
"sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b",
|
||||
"sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1",
|
||||
"sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531",
|
||||
"sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1",
|
||||
"sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11",
|
||||
"sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326",
|
||||
"sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df",
|
||||
"sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.0'",
|
||||
"version": "==3.1.0"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
|
||||
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.0'",
|
||||
"version": "==8.1.3"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:7eb373984bf1c770023fce9db164ed0c3353cd0b53f130f4693da0ca756a2e6d",
|
||||
"sha256:c0bec9477df1cb867e5a67c9e1ab758de9cb4a3e52dd70681f59fa40a62b3f2d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.2.3"
|
||||
},
|
||||
"flask-json": {
|
||||
"hashes": [
|
||||
"sha256:0701576a2ddb78eb11fd74c143871e01205537c4a83dbc81cd3796ca68627f86",
|
||||
"sha256:b641a2125cb6984e7eafc921c9bf70c214ea4faff9a0bb1a75a4ec5749f3e67c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.3.5"
|
||||
},
|
||||
"flask-socketio": {
|
||||
"hashes": [
|
||||
"sha256:04093e3ca144467f9731c376796aff105d182ac4cccfcb056d05d567a675f306",
|
||||
"sha256:11d1d78b8805cda351b27828a110b88c74a573be62b07f7f5a519fb67fae0a58"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.3.2"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4",
|
||||
"sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==3.4"
|
||||
},
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
"sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad",
|
||||
"sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d"
|
||||
],
|
||||
"markers": "python_version < '3.10'",
|
||||
"version": "==6.0.0"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
"sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44",
|
||||
"sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.0'",
|
||||
"version": "==2.1.2"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852",
|
||||
"sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.0'",
|
||||
"version": "==3.1.2"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed",
|
||||
"sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc",
|
||||
"sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2",
|
||||
"sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460",
|
||||
"sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7",
|
||||
"sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0",
|
||||
"sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1",
|
||||
"sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa",
|
||||
"sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03",
|
||||
"sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323",
|
||||
"sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65",
|
||||
"sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013",
|
||||
"sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036",
|
||||
"sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f",
|
||||
"sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4",
|
||||
"sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419",
|
||||
"sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2",
|
||||
"sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619",
|
||||
"sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a",
|
||||
"sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a",
|
||||
"sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd",
|
||||
"sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7",
|
||||
"sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666",
|
||||
"sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65",
|
||||
"sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859",
|
||||
"sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625",
|
||||
"sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff",
|
||||
"sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156",
|
||||
"sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd",
|
||||
"sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba",
|
||||
"sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f",
|
||||
"sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1",
|
||||
"sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094",
|
||||
"sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a",
|
||||
"sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513",
|
||||
"sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed",
|
||||
"sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d",
|
||||
"sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3",
|
||||
"sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147",
|
||||
"sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c",
|
||||
"sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603",
|
||||
"sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601",
|
||||
"sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a",
|
||||
"sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1",
|
||||
"sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d",
|
||||
"sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3",
|
||||
"sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54",
|
||||
"sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2",
|
||||
"sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6",
|
||||
"sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.0'",
|
||||
"version": "==2.1.2"
|
||||
},
|
||||
"python-engineio": {
|
||||
"hashes": [
|
||||
"sha256:7454314a529bba20e745928601ffeaf101c1b5aca9a6c4e48ad397803d10ea0c",
|
||||
"sha256:d8d8b072799c36cadcdcc2b40d2a560ce09797ab3d2d596b2ad519a5e4df19ae"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==4.3.4"
|
||||
},
|
||||
"python-socketio": {
|
||||
"hashes": [
|
||||
"sha256:92395062d9db3c13d30e7cdedaa0e1330bba78505645db695415f9a3c628d097",
|
||||
"sha256:d9a9f047e6fdd306c852fbac36516f4b495c2096f8ad9ceb8803b8e5ff5622e3"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==5.7.2"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa",
|
||||
"sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.28.2"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72",
|
||||
"sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
|
||||
"version": "==1.26.14"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe",
|
||||
"sha256:56433961bc1f12533306c624f3be5e744389ac61d722175d543e1751285da612"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.0'",
|
||||
"version": "==2.2.3"
|
||||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b",
|
||||
"sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.0'",
|
||||
"version": "==3.15.0"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
51
app.py
Normal file
51
app.py
Normal file
@ -0,0 +1,51 @@
|
||||
from flask import Flask, render_template
|
||||
from flask_json import FlaskJSON, as_json
|
||||
import requests
|
||||
from flask_socketio import SocketIO
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['SECRET_KEY'] = 'secret'
|
||||
json = FlaskJSON(app)
|
||||
socketio = SocketIO(app, logger=True, log_output=True)
|
||||
socketio.init_app(app, cors_allowed_origins="*")
|
||||
|
||||
CURRENT_LISTENERS = 0
|
||||
|
||||
def heartbeat():
|
||||
global CURRENT_LISTENERS
|
||||
backendFetch = requests.get('http://hackerbots.net:8000/status-json.xsl')
|
||||
stats = backendFetch.json()['icestats']['source']
|
||||
print(stats)
|
||||
return {
|
||||
'title': stats.get('title', 'Unknown Track'),
|
||||
'listeners': CURRENT_LISTENERS,
|
||||
'show_title': 'Flask Test Show'
|
||||
}
|
||||
|
||||
@socketio.on('live.hello')
|
||||
def on_hello(*args, **kwargs):
|
||||
print("Hello!!!")
|
||||
|
||||
@socketio.on('connect')
|
||||
def on_new_listener():
|
||||
global CURRENT_LISTENERS
|
||||
CURRENT_LISTENERS += 1
|
||||
socketio.emit('live.heartbeat', heartbeat())
|
||||
|
||||
@socketio.on('disconnect')
|
||||
def on_new_listener():
|
||||
global CURRENT_LISTENERS
|
||||
CURRENT_LISTENERS -= 1
|
||||
socketio.emit('live.heartbeat', heartbeat())
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
@app.route("/status.json")
|
||||
@as_json
|
||||
def status():
|
||||
return heartbeat()
|
||||
|
||||
if __name__ == '__main__':
|
||||
socketio.run(app, port=5000, host='0.0.0.0')
|
208
index.html
208
index.html
@ -1,208 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>live.hackerbots.net</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- <script type="text/javascript" src="../dist/butterchurn.js"></script> -->
|
||||
<script type="text/javascript" src="https://unpkg.com/lodash"></script>
|
||||
<script type="text/javascript" src="https://unpkg.com/butterchurn"></script>
|
||||
<script type="text/javascript" src="https://unpkg.com/butterchurn-presets"></script>
|
||||
<script type="text/javascript" src="https://unpkg.com/butterchurn-presets/lib/butterchurnPresetsExtra.min.js"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Bungee+Spice&display=swap" rel="stylesheet">
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.1.1.min.js"
|
||||
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
|
||||
crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/normalize.css/normalize.css" />
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
var visualizer = null;
|
||||
var rendering = false;
|
||||
var sourceNode = null;
|
||||
var delayedAudible = null;
|
||||
var cycleInterval = null;
|
||||
var presets = {};
|
||||
var presetKeys = [];
|
||||
var presetIndexHist = [];
|
||||
var presetIndex = 0;
|
||||
var presetCycle = true;
|
||||
var presetCycleLength = 15000;
|
||||
var presetRandom = true;
|
||||
|
||||
function startRenderer() {
|
||||
if (!document.hidden && visualizer) {
|
||||
var fps = 60;
|
||||
setTimeout(() => {
|
||||
requestAnimationFrame(startRenderer);
|
||||
}, 1000 / fps);
|
||||
visualizer.render();
|
||||
}
|
||||
}
|
||||
|
||||
function visToggle() {
|
||||
if (!document.hidden) {
|
||||
startRenderer();
|
||||
}
|
||||
}
|
||||
document.addEventListener('visibilitychange', visToggle);
|
||||
|
||||
function initPlayer() {
|
||||
var audioContext = new AudioContext();
|
||||
var mediaElement = document.getElementById('audio-player');
|
||||
var mediaSrc = audioContext.createMediaElementSource(mediaElement);
|
||||
|
||||
//var canvas = document.getElementById('canvas');
|
||||
var canvas = document.createElement('canvas');
|
||||
document.body.appendChild(canvas);
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
visualizer = butterchurn.default.createVisualizer(audioContext, canvas , {
|
||||
width: canvas.width,
|
||||
height: canvas.height,
|
||||
pixelRatio: window.devicePixelRatio || 1,
|
||||
textureRatio: 1,
|
||||
});
|
||||
|
||||
mediaSrc.connect(audioContext.destination);
|
||||
visualizer.connectAudio(mediaSrc);
|
||||
|
||||
var presets = {};
|
||||
if (window.butterchurnPresets) {
|
||||
Object.assign(presets, butterchurnPresets.getPresets());
|
||||
}
|
||||
if (window.butterchurnPresetsExtra) {
|
||||
Object.assign(presets, butterchurnPresetsExtra.getPresets());
|
||||
}
|
||||
|
||||
visualizer.loadPreset(_.sample(presets));
|
||||
|
||||
cycleInterval = setInterval(() => {
|
||||
visualizer.loadPreset(_.sample(presets), 5.7);
|
||||
}, presetCycleLength);
|
||||
|
||||
$(canvas).click(() => {
|
||||
visualizer.loadPreset(_.sample(presets), 1.0);
|
||||
});
|
||||
}
|
||||
|
||||
function updateMeta() {
|
||||
$.getJSON('/status.json', (data) => {
|
||||
var meta = data.icestats.source;
|
||||
var title = meta.title;
|
||||
var listeners = meta.listeners;
|
||||
console.log(data.icestats.source);
|
||||
$('#title').text(title);
|
||||
$('#listeners').text(listeners + " listeners");
|
||||
});
|
||||
}
|
||||
|
||||
updateMeta();
|
||||
setInterval(updateMeta, 3000);
|
||||
|
||||
var isSetup = false;
|
||||
|
||||
$('#the-button').click(() => {
|
||||
if (!isSetup) {
|
||||
initPlayer();
|
||||
isSetup = true;
|
||||
$('#the-button').remove();
|
||||
startRenderer();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style type="text/css">
|
||||
html, body, #canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
animation: rainbow-bg 10s linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
#the-button {
|
||||
animation: throb 2.5s ease-in-out infinite alternate;
|
||||
font-family: 'Bungee Spice', cursive;
|
||||
font-size: 6em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#metadata {
|
||||
position: absolute;
|
||||
bottom: 0%;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
z-index: 1000;
|
||||
color: #fff;
|
||||
font-family: 'Bungee Spice', sans-serif;
|
||||
text-align: center;
|
||||
padding: 3rem;
|
||||
}
|
||||
|
||||
#title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
@keyframes rainbow-bg{
|
||||
100%,0%{
|
||||
background-color: rgb(255,0,0);
|
||||
}
|
||||
8%{
|
||||
background-color: rgb(255,127,0);
|
||||
}
|
||||
16%{
|
||||
background-color: rgb(255,255,0);
|
||||
}
|
||||
25%{
|
||||
background-color: rgb(127,255,0);
|
||||
}
|
||||
33%{
|
||||
background-color: rgb(0,255,0);
|
||||
}
|
||||
41%{
|
||||
background-color: rgb(0,255,127);
|
||||
}
|
||||
50%{
|
||||
background-color: rgb(0,255,255);
|
||||
}
|
||||
58%{
|
||||
background-color: rgb(0,127,255);
|
||||
}
|
||||
66%{
|
||||
background-color: rgb(0,0,255);
|
||||
}
|
||||
75%{
|
||||
background-color: rgb(127,0,255);
|
||||
}
|
||||
83%{
|
||||
background-color: rgb(255,0,255);
|
||||
}
|
||||
91%{
|
||||
background-color: rgb(255,0,127);
|
||||
}
|
||||
}
|
||||
@keyframes throb{
|
||||
from{
|
||||
transform: scale(1.0);
|
||||
}
|
||||
to {
|
||||
transform: scale(0.75);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<audio id='audio-player' autoplay src="https://live.hackerbots.net/listen.mp3">No audio</audio>
|
||||
<div id="the-button">HIT IT, JACK ▶</div>
|
||||
<div id="metadata"><span id="title"></span><p><span id="listeners"></span></div>
|
||||
</body>
|
||||
</html>
|
116
static/main.css
Normal file
116
static/main.css
Normal file
@ -0,0 +1,116 @@
|
||||
html, body, #canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.butterviz {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
animation: rainbow-bg 10s linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
#loader {
|
||||
font-size: xx-large;
|
||||
font-family: 'Bungee Spice';
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
transition: all .75s ease;
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#loader p {
|
||||
padding: 10rem 5rem 1rem 5rem;
|
||||
background: url(/static/raccoon.gif);
|
||||
background-repeat: no-repeat;
|
||||
background-position: top center;
|
||||
}
|
||||
|
||||
#loader.show {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#the-button {
|
||||
animation: throb 2.5s ease-in-out infinite alternate;
|
||||
font-family: 'Bungee Spice', cursive;
|
||||
font-size: 6em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#metadata {
|
||||
position: absolute;
|
||||
bottom: 0%;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
z-index: 1000;
|
||||
color: #fff;
|
||||
font-family: 'Bungee Spice', sans-serif;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
padding-top: 3rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
padding-bottom: 3rem;
|
||||
}
|
||||
|
||||
#title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
@keyframes rainbow-bg{
|
||||
100%,0%{
|
||||
background-color: rgb(255,0,0);
|
||||
}
|
||||
8%{
|
||||
background-color: rgb(255,127,0);
|
||||
}
|
||||
16%{
|
||||
background-color: rgb(255,255,0);
|
||||
}
|
||||
25%{
|
||||
background-color: rgb(127,255,0);
|
||||
}
|
||||
33%{
|
||||
background-color: rgb(0,255,0);
|
||||
}
|
||||
41%{
|
||||
background-color: rgb(0,255,127);
|
||||
}
|
||||
50%{
|
||||
background-color: rgb(0,255,255);
|
||||
}
|
||||
58%{
|
||||
background-color: rgb(0,127,255);
|
||||
}
|
||||
66%{
|
||||
background-color: rgb(0,0,255);
|
||||
}
|
||||
75%{
|
||||
background-color: rgb(127,0,255);
|
||||
}
|
||||
83%{
|
||||
background-color: rgb(255,0,255);
|
||||
}
|
||||
91%{
|
||||
background-color: rgb(255,0,127);
|
||||
}
|
||||
}
|
||||
@keyframes throb{
|
||||
from{
|
||||
transform: scale(1.0);
|
||||
}
|
||||
to {
|
||||
transform: scale(0.75);
|
||||
}
|
||||
}
|
60
static/main.js
Normal file
60
static/main.js
Normal file
@ -0,0 +1,60 @@
|
||||
import { io } from "https://cdn.socket.io/4.4.1/socket.io.esm.min.js"
|
||||
import Visualizer from "./viz.js"
|
||||
|
||||
export function init() {
|
||||
function updateMeta(data) {
|
||||
var title = data.title;
|
||||
var listeners = data.listeners;
|
||||
$('#title').text(title);
|
||||
$('#listeners').text(listeners + " listeners");
|
||||
}
|
||||
|
||||
function visToggle() {
|
||||
if (!document.hidden) {
|
||||
visualizer.start();
|
||||
}
|
||||
}
|
||||
document.addEventListener('visibilitychange', visToggle);
|
||||
|
||||
var visualizer = null;
|
||||
var audioPlayer = document.getElementById("audio-player");
|
||||
var loaderWidget = document.getElementById("loader");
|
||||
|
||||
$('#the-button').click(() => {
|
||||
if (visualizer == null) {
|
||||
|
||||
audioPlayer.play();
|
||||
|
||||
$(loaderWidget).addClass("show");
|
||||
$('#the-button').remove();
|
||||
|
||||
setTimeout(() => {
|
||||
visualizer = new Visualizer(audioPlayer);
|
||||
setTimeout(() => {
|
||||
visualizer.start();
|
||||
}, 0);
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
|
||||
var socket = io();
|
||||
socket.on('connect', () => {
|
||||
socket.emit('live.hello', {});
|
||||
});
|
||||
socket.on('live.heartbeat', (heartbeat) => {
|
||||
console.log('heartbeat')
|
||||
console.log(heartbeat)
|
||||
updateMeta(heartbeat)
|
||||
});
|
||||
|
||||
window.addEventListener("resize", _.debounce(() => {
|
||||
visualizer.resize();
|
||||
}, 100));
|
||||
|
||||
audioPlayer.addEventListener("waiting", (evt) => {
|
||||
$(loaderWidget).addClass("show");
|
||||
});
|
||||
audioPlayer.addEventListener("playing", (evt) => {
|
||||
$(loaderWidget).removeClass("show");
|
||||
});
|
||||
}
|
BIN
static/raccoon.gif
Normal file
BIN
static/raccoon.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
67
static/viz.js
Normal file
67
static/viz.js
Normal file
@ -0,0 +1,67 @@
|
||||
import "https://unpkg.com/butterchurn@2.6.7"
|
||||
import "https://unpkg.com/butterchurn-presets@2.4.7"
|
||||
import "https://unpkg.com/butterchurn-presets/lib/butterchurnPresetsExtra.min.js"
|
||||
|
||||
export default class Visualizer {
|
||||
butterViz = null;
|
||||
canvas = null;
|
||||
cycleInterval = null;
|
||||
presetCycleLength = 15000;
|
||||
|
||||
constructor(mediaElement) {
|
||||
var audioContext = new AudioContext();
|
||||
var mediaSrc = audioContext.createMediaElementSource(mediaElement);
|
||||
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.canvas.className = "butterviz";
|
||||
document.body.appendChild(this.canvas);
|
||||
this.canvas.width = this.canvas.offsetWidth;
|
||||
this.canvas.height = this.canvas.offsetHeight;
|
||||
this.butterViz = butterchurn.default.createVisualizer(audioContext, this.canvas , {
|
||||
width: this.canvas.width,
|
||||
height: this.canvas.height,
|
||||
pixelRatio: window.devicePixelRatio || 1,
|
||||
textureRatio: 1,
|
||||
});
|
||||
|
||||
mediaSrc.connect(audioContext.destination);
|
||||
this.butterViz.connectAudio(mediaSrc);
|
||||
|
||||
var presets = {};
|
||||
if (window.butterchurnPresets) {
|
||||
Object.assign(presets, butterchurnPresets.getPresets());
|
||||
}
|
||||
if (window.butterchurnPresetsExtra) {
|
||||
Object.assign(presets, butterchurnPresetsExtra.getPresets());
|
||||
}
|
||||
|
||||
this.cycleInterval = setInterval(() => {
|
||||
this.butterViz.loadPreset(_.sample(presets), 5.7);
|
||||
}, this.presetCycleLength);
|
||||
|
||||
$(this.canvas).click(() => {
|
||||
this.butterViz.loadPreset(_.sample(presets), 1.0);
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this.butterViz.loadPreset(_.sample(presets));
|
||||
}, 0);
|
||||
|
||||
}
|
||||
|
||||
resize() {
|
||||
this.canvas.width = window.innerWidth;
|
||||
this.canvas.height = window.innerHeight;
|
||||
this.butterViz.setRendererSize(this.canvas.offsetWidth, this.canvas.offsetHeight);
|
||||
}
|
||||
|
||||
start() {
|
||||
if (!document.hidden && this.butterViz) {
|
||||
var fps = 60;
|
||||
setTimeout(() => {
|
||||
requestAnimationFrame(() => {this.start()});
|
||||
}, 1000 / fps);
|
||||
this.butterViz.render();
|
||||
}
|
||||
}
|
||||
}
|
31
templates/index.html
Normal file
31
templates/index.html
Normal file
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>live.hackerbots.net</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<script type="text/javascript" src="https://unpkg.com/lodash"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Bungee+Spice&display=swap" rel="stylesheet">
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.1.1.min.js"
|
||||
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
|
||||
crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/normalize.css/normalize.css" />
|
||||
|
||||
<script type="module">
|
||||
import { init } from "/static/main.js"
|
||||
$(init)
|
||||
</script>
|
||||
<link rel="stylesheet" href="/static/main.css" />
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<audio crossorigin="anonymous" id='audio-player' src="https://live.hackerbots.net/listen.mp3">No audio</audio>
|
||||
<div id="loader"><p>Buffering...</p></div>
|
||||
<div id="the-button">HIT IT, JACK ▶</div>
|
||||
<div id="metadata"><div id="title">Loading...</div><div id="listeners"></div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user