├── .gitignore ├── .vs ├── ProjectSettings.json ├── VSWorkspaceState.json ├── bogodownload │ └── v16 │ │ └── .suo └── slnx.sqlite ├── README.md ├── banner.png ├── client.py ├── client_files └── joke.txt ├── demo.png ├── server.py └── server_files ├── joke.txt └── linus.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /.vs/ProjectSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "CurrentProjectSetting": null 3 | } -------------------------------------------------------------------------------- /.vs/VSWorkspaceState.json: -------------------------------------------------------------------------------- 1 | { 2 | "ExpandedNodes": [ 3 | "" 4 | ], 5 | "PreviewInSolutionExplorer": false 6 | } -------------------------------------------------------------------------------- /.vs/bogodownload/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Roadcrosser/bogodownload/a0966941afbb083d58f2d505c16726c18321ffbf/.vs/bogodownload/v16/.suo -------------------------------------------------------------------------------- /.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Roadcrosser/bogodownload/a0966941afbb083d58f2d505c16726c18321ffbf/.vs/slnx.sqlite -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bogodownload 2 | 3 | ![Bogodownload Banner](banner.png) 4 | 5 | Applying the stupidity of bogosort to file transfers is the height of folly. 6 | 7 | ### What is it? 8 | Bogosort is the sorting method that constantly permutates an array until the result is sorted. 9 | 10 | What would happen, then, if you applied those principles to file transfer? Bogodownload attempts to answer that question. 11 | 12 | ### But what is it though? 13 | 14 | Bogodownload is a file transfer system using websockets, currently implemented in Python. 15 | 16 | The server uses `Quart` and the client uses `aiohttp` and `websockets`. 17 | 18 | When the client requests a file from the server via a websocket connection, data will be returned as such: 19 | 20 | ```json 21 | {"size":1024, "pos":512, "byte":32} 22 | ``` 23 | 24 | The `size` parameter denotes the amount of bytes in the file, while the `byte` returned will correspond to its `pos`ition in the file, and will be random for each message. The server will continuously send these json messages through the websocket until the client cuts off the connection, usually when it has finished downloading the entire file. 25 | 26 | ![Bogodownload Banner](demo.png) 27 | 28 | ### But why though? 29 | 30 | I needed something to do after I finished making [JSON-G](https://github.com/Roadcrosser/JSON-G) okay? Get off my back. -------------------------------------------------------------------------------- /banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Roadcrosser/bogodownload/a0966941afbb083d58f2d505c16726c18321ffbf/banner.png -------------------------------------------------------------------------------- /client.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import websockets 3 | import json 4 | 5 | fn = "linus.jpg" 6 | uri = f"ws://localhost:5000/bogodownload/{fn}" 7 | 8 | client_dir = "client_files" 9 | 10 | async def hello(): 11 | ls = [None] 12 | async with websockets.connect(uri) as websocket: 13 | last = -1 14 | iters = 0 15 | while None in ls: 16 | resp = await websocket.recv() 17 | resp = json.loads(resp) 18 | size = resp["size"] 19 | 20 | if len(ls) != size: 21 | ls = [None] * size 22 | 23 | ls[resp["pos"]] = resp["byte"] 24 | 25 | now = sum(1 for i in ls if i != None) 26 | if now > last: 27 | last = now 28 | print(f"{now}/{len(ls)}") 29 | 30 | iters += 1 31 | 32 | 33 | with open(f"{client_dir}/{fn}", "wb+") as w: 34 | w.write(bytes(ls)) 35 | 36 | print(f"Received {fn} ({size} bytes) in ({iters} byte transfers). (In)efficiency: {(iters/size) * 100}%") 37 | 38 | asyncio.get_event_loop().run_until_complete(hello()) 39 | -------------------------------------------------------------------------------- /client_files/joke.txt: -------------------------------------------------------------------------------- 1 | Wenn ist das Nunstück git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput! -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Roadcrosser/bogodownload/a0966941afbb083d58f2d505c16726c18321ffbf/demo.png -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | from quart import Quart, websocket 2 | import asyncio 3 | import random 4 | import json 5 | import os 6 | 7 | app = Quart(__name__) 8 | 9 | interval = 0 10 | server_dir = "server_files" 11 | 12 | @app.websocket('/bogodownload/') 13 | async def bogo(fn): 14 | filename = None 15 | for f in os.listdir(server_dir): 16 | if f == fn and os.path.isfile(f"{server_dir}/{f}"): 17 | filename = f 18 | if not filename: 19 | return 20 | 21 | with open(f"{server_dir}/{filename}", "rb") as o: 22 | to_send = list(o.read()) 23 | bytelength = len(to_send) 24 | 25 | try: 26 | while True: 27 | bytepos = random.randint(0, bytelength-1) 28 | await websocket.send( 29 | json.dumps( 30 | { 31 | "size": bytelength, 32 | "pos": bytepos, 33 | "byte": to_send[bytepos] 34 | } 35 | ) 36 | ) 37 | await asyncio.sleep(interval) 38 | finally: 39 | ... 40 | 41 | app.run() -------------------------------------------------------------------------------- /server_files/joke.txt: -------------------------------------------------------------------------------- 1 | Wenn ist das Nunstück git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput! -------------------------------------------------------------------------------- /server_files/linus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Roadcrosser/bogodownload/a0966941afbb083d58f2d505c16726c18321ffbf/server_files/linus.jpg --------------------------------------------------------------------------------