Changed treehug again
This commit is contained in:
parent
5f30b430ff
commit
cc472c0df4
136
src/treehug/frmWrk/.gitignore
vendored
136
src/treehug/frmWrk/.gitignore
vendored
|
@ -1,136 +0,0 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
clearLogs.py
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
test.py
|
||||
test/
|
||||
|
||||
# website/
|
||||
.vscode/
|
||||
log.txt
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
|
@ -1,62 +0,0 @@
|
|||
|
||||
|
||||
[Installation](#installing)
|
||||
|
||||
[Quickstart](#usage)
|
||||
|
||||
[Documentation](#documentation)
|
||||
|
||||
# Installing
|
||||
|
||||
Open terminal in project folder.
|
||||
Run:
|
||||
```bash
|
||||
git clone https://github.com/vanten-s/frmWrk frmWrk
|
||||
```
|
||||
|
||||
Done. Look at usage for quickstart.
|
||||
|
||||
# Usage
|
||||
|
||||
With a index.html in the working directory this will make host a website at 127.0.0.1
|
||||
|
||||
```python
|
||||
# Example for website
|
||||
|
||||
import frmWrk.website as frw
|
||||
|
||||
# Start the server on 127.0.0.1:80 with parent folder as root directory
|
||||
website = frw.WebServer("127.0.0.1", 80, "./")
|
||||
website.start()
|
||||
|
||||
# Close the server when we get input
|
||||
input()
|
||||
website.close()
|
||||
|
||||
```
|
||||
|
||||
# Documentation
|
||||
|
||||
```python
|
||||
# Import everything
|
||||
|
||||
import frmWrk
|
||||
import time
|
||||
|
||||
# Create the webserver. Directory is where the server should look for files
|
||||
website = frmWrk.website.WebServer(ip, port, directory)
|
||||
|
||||
# Run the server
|
||||
website.start()
|
||||
|
||||
# Wait 10 seconds and close the server
|
||||
time.sleep(10)
|
||||
|
||||
website.close()
|
||||
```
|
||||
|
||||
frmWrk will replace substrings in the format of {ip:port:prompt} by connecting to (ip, port) and sending "{promt} {path}" where path is the URL that the user is on. Then they replace the whole substring with the response (max 1024 bytes).
|
||||
|
||||
frmWrk.databases should not be used.
|
||||
It Can be used but please dont use it.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
import frmWrk.website
|
||||
import frmWrk.decorators
|
|
@ -1,192 +0,0 @@
|
|||
|
||||
|
||||
import socket
|
||||
import threading
|
||||
import datetime
|
||||
|
||||
enable_logging = True
|
||||
log_file = "log.txt"
|
||||
|
||||
def log(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
if not enable_logging: return func(*args, **kwargs)
|
||||
returnVal = func(*args, **kwargs)
|
||||
with open(log_file, "a") as f:
|
||||
try:
|
||||
if len(returnVal) < 100:
|
||||
f.write(f"{func.__name__} was called at {datetime.datetime.now().strftime('%m/%d/%Y, %H:%M:%S')} and returned {returnVal}\n")
|
||||
else:
|
||||
f.write(f"{func.__name__} was called at {datetime.datetime.now().strftime('%m/%d/%Y, %H:%M:%S')}\n")
|
||||
except TypeError as e:
|
||||
f.write(f"{func.__name__} was called at {datetime.datetime.now().strftime('%m/%d/%Y, %H:%M:%S')}\n")
|
||||
|
||||
return returnVal
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def log_string(string):
|
||||
if not enable_logging: return string
|
||||
with open(log_file, "a") as f:
|
||||
f.write(f"{string}\n")
|
||||
return string
|
||||
|
||||
|
||||
|
||||
|
||||
databases = {}
|
||||
__using_remote_access = False
|
||||
|
||||
"""
|
||||
Usage:
|
||||
CREATE <name> # Creates a new database
|
||||
ADDATTRIBUTE <name> <attribute> # Adds an attribute to a database
|
||||
ADD <name> <database> # Adds an entry to a database
|
||||
LIST # Lists all databases
|
||||
GET <entry> <database> <attribute> # Gets an entry from a database
|
||||
SET <entry> <database> <attribute> <value> # Sets an attribute of an entry in a database
|
||||
|
||||
|
||||
"""
|
||||
|
||||
def help():
|
||||
return "Usage: CREATE <name> # Creates a new database\nADDATTRIBUTE <name> <attribute> # Adds an attribute to a database\nADD <name> <database> # Adds an entry to a database\nLIST # Lists all databases\nGET <entry> <database> # Gets an entry from a database\nSET <entry> <database> <attribute> <value> # Sets an attribute of an entry in a database"
|
||||
|
||||
|
||||
class Database:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.attributes = []
|
||||
self.entrys = {}
|
||||
databases[name] = self
|
||||
|
||||
def __hash__(self):
|
||||
return self.name
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.name == other.name
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def __repr__(self):
|
||||
return self.name
|
||||
|
||||
def addAttribute(self, attribute):
|
||||
self.attributes.append(attribute)
|
||||
for entry in self.entrys:
|
||||
entry.__setAttribute(attribute)
|
||||
|
||||
def getAttribute(self, attribute):
|
||||
return self.attributes[attribute]
|
||||
|
||||
|
||||
|
||||
class Entry:
|
||||
def __init__(self, name, parent):
|
||||
self.name = name
|
||||
self.parent = parent
|
||||
self.attributes = {attr:None for attr in parent.attributes}
|
||||
self.parent.entrys[name] = self
|
||||
|
||||
def __hash__(self):
|
||||
return self.name
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.name == other.name
|
||||
|
||||
def __str__(self):
|
||||
return self.attributes.__str__()
|
||||
|
||||
def __repr__(self):
|
||||
return self.name + " with " + self.attributes.__str__()
|
||||
|
||||
def __setAttribute(self, attribute):
|
||||
self.attributes[attribute] = ""
|
||||
|
||||
def setAttribute(self, attribute, value):
|
||||
if attribute in self.attributes.keys():
|
||||
self.attributes[attribute] = value
|
||||
else:
|
||||
raise Exception("Attribute not found")
|
||||
|
||||
def getAttribute(self, attribute):
|
||||
if attribute in self.attributes.keys():
|
||||
return self.attributes[attribute]
|
||||
else:
|
||||
raise Exception("Attribute not found")
|
||||
|
||||
|
||||
def executeInstruction(instruction):
|
||||
tokens = instruction.split(" ")
|
||||
log_string(f"Executing instruction: {instruction}")
|
||||
if tokens[0] == "CREATE":
|
||||
database = Database(tokens[1])
|
||||
return database
|
||||
|
||||
elif tokens[0] == "ADDATTRIBUTE":
|
||||
databases[tokens[1]].addAttribute(tokens[2])
|
||||
|
||||
elif tokens[0] == "ADD":
|
||||
Entry(tokens[1], databases[tokens[2]])
|
||||
|
||||
elif tokens[0] == "LIST":
|
||||
if len(databases) == 0:
|
||||
return "No databases"
|
||||
|
||||
if len(tokens) == 2:
|
||||
return databases[tokens[1]].entrys
|
||||
|
||||
if len(tokens) == 3:
|
||||
return databases[tokens[1]].entrys[tokens[2]]
|
||||
|
||||
return databases
|
||||
|
||||
elif tokens[0] == "GET":
|
||||
return databases[tokens[1]].entrys[tokens[2]].getAttribute(tokens[3]).__str__()
|
||||
|
||||
elif tokens[0] == "SET":
|
||||
database = databases[tokens[1]].entrys[tokens[2]].setAttribute(tokens[3], tokens[4])
|
||||
|
||||
else:
|
||||
print(instruction)
|
||||
return "Invalid instruction"
|
||||
|
||||
return "Success"
|
||||
|
||||
def __enable_remote_access(ip, port):
|
||||
HOST = ip # The server's hostname or IP address
|
||||
PORT = port # The port used by the server
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.bind((HOST, PORT))
|
||||
s.listen(1)
|
||||
while True and __using_remote_access:
|
||||
conn, addr = s.accept()
|
||||
with conn:
|
||||
print('Connected by', addr)
|
||||
while True:
|
||||
data = conn.recv(1024).decode()
|
||||
|
||||
firstLine = data.split("\n")[0]
|
||||
instruction = " ".join(firstLine.split(" ")[1:-1])
|
||||
|
||||
conn.send(executeInstruction(instruction).encode())
|
||||
if not data: break
|
||||
|
||||
|
||||
print('Connection closed')
|
||||
|
||||
@log
|
||||
def enable_remote_access(ip, port):
|
||||
global __using_remote_access
|
||||
__using_remote_access = True
|
||||
t = threading.Thread(target=__enable_remote_access, args=(ip, port))
|
||||
t.start()
|
||||
return "Enabled remote access"
|
||||
|
||||
def disable_remote_access():
|
||||
global __using_remote_access
|
||||
__using_remote_access = False
|
||||
return "Disabled remote access"
|
||||
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
import datetime
|
||||
|
||||
enable_logging = True
|
||||
log_file = "log.txt"
|
||||
|
||||
def log(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
if not enable_logging: return func(*args, **kwargs)
|
||||
returnVal = func(*args, **kwargs)
|
||||
with open(log_file, "a") as f:
|
||||
try:
|
||||
if len(returnVal) < 100:
|
||||
f.write(f"{func.__name__} was called at {datetime.datetime.now().strftime('%m/%d/%Y, %H:%M:%S')} and returned {returnVal}\n")
|
||||
else:
|
||||
f.write(f"{func.__name__} was called at {datetime.datetime.now().strftime('%m/%d/%Y, %H:%M:%S')}\n")
|
||||
except TypeError as e:
|
||||
f.write(f"{func.__name__} was called at {datetime.datetime.now().strftime('%m/%d/%Y, %H:%M:%S')}\n")
|
||||
|
||||
return returnVal
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def log_string(string):
|
||||
if not enable_logging: return string
|
||||
with open(log_file, "a") as f:
|
||||
f.write(f"{string}\n")
|
||||
return string
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 3.7 KiB |
File diff suppressed because one or more lines are too long
|
@ -1,300 +0,0 @@
|
|||
|
||||
import socket
|
||||
import threading
|
||||
import datetime
|
||||
import os
|
||||
|
||||
def boron (code: str, path: str) -> str:
|
||||
total = []
|
||||
none = []
|
||||
|
||||
while "{" in code and "}" in code:
|
||||
startIndex = code.index("{")
|
||||
endIndex = code.index("}")
|
||||
try:
|
||||
string = code[startIndex+1:endIndex]
|
||||
ip = string.split(":")[0]
|
||||
port = int(string.split(":")[1])
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
addr = (ip, port)
|
||||
print(addr)
|
||||
s.connect(addr)
|
||||
s.send((string.split(":")[2] + " " + path).encode('utf-8'))
|
||||
response = s.recv(1024).decode()
|
||||
s.close()
|
||||
code = code.replace("{" + string + "}", response)
|
||||
print("{" + string + "}")
|
||||
print(code)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
code = code.replace("{" + string + "}", string)
|
||||
none.append(string)
|
||||
print("{" + string + "}")
|
||||
print(code)
|
||||
|
||||
for string in none:
|
||||
code = code.replace(string, "{" + string + "}")
|
||||
|
||||
return code
|
||||
|
||||
|
||||
enable_logging = True
|
||||
log_file = "log.txt"
|
||||
|
||||
def log(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
if not enable_logging: return func(*args, **kwargs)
|
||||
returnVal = func(*args, **kwargs)
|
||||
try:
|
||||
if len(returnVal) < 10:
|
||||
log_string(f"[{datetime.datetime.now().strftime('%m/%d/%Y, %H:%M:%S')}] {func.__name__} was called and returned {returnVal}\n")
|
||||
else:
|
||||
log_string(f"[{datetime.datetime.now().strftime('%m/%d/%Y, %H:%M:%S')}] {func.__name__} was called\n")
|
||||
except TypeError as e:
|
||||
log_string(f"[{datetime.datetime.now().strftime('%m/%d/%Y, %H:%M:%S')}] {func.__name__} was called\n")
|
||||
|
||||
return returnVal
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def log_string(string):
|
||||
global log_file, enable_logging
|
||||
if not enable_logging: return
|
||||
with open(log_file, "a") as f:
|
||||
f.write(f"[{datetime.datetime.now().strftime('%m/%d/%Y, %H:%M:%S')}] {string}\n")
|
||||
|
||||
return string
|
||||
|
||||
AASCI_404_NOT_FOUND = """
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>404 Not Found</h1>
|
||||
<pre style="font-size: xx-large;">
|
||||
_ _ ___ _ _ _ __ _
|
||||
| || | / _ \| || | | | / _| | |
|
||||
| || |_| | | | || |_ _ __ ___ | |_ | |_ ___ _ _ _ __ __| |
|
||||
|__ _| | | |__ _| | '_ \ / _ \| __| | _/ _ \| | | | '_ \ / _` |
|
||||
| | | |_| | | | | | | | (_) | |_ | || (_) | |_| | | | | (_| |
|
||||
|_| \___/ |_| |_| |_|\___/ \__| |_| \___/ \__,_|_| |_|\__,_|</pre>
|
||||
|
||||
</body>
|
||||
|
||||
"""
|
||||
|
||||
content_type = {
|
||||
'html': 'text/html; charset=\'utf-8\'',
|
||||
'css': 'text/css; charset=\'utf-8\'',
|
||||
'js': 'application/javascript; charset=\'utf-8\'',
|
||||
'xml': 'application/xml; charset=\'utf-8\'',
|
||||
'png': 'image/png',
|
||||
'jpg': 'image/jpeg',
|
||||
'jpeg': 'image/jpeg',
|
||||
'gif': 'image/gif',
|
||||
'ico': 'image/x-icon',
|
||||
'svg': 'image/svg+xml',
|
||||
'json': 'application/json; charset=\'utf-8\'',
|
||||
'txt': 'text/plain; charset=\'utf-8\'',
|
||||
'pdf': 'application/pdf',
|
||||
'zip': 'application/zip',
|
||||
'rar': 'application/x-rar-compressed',
|
||||
'7z': 'application/x-7z-compressed',
|
||||
'doc': 'application/msword',
|
||||
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'xls': 'application/vnd.ms-excel',
|
||||
'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'ppt': 'application/vnd.ms-powerpoint',
|
||||
'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'mp3': 'audio/mpeg',
|
||||
'wav': 'audio/x-wav',
|
||||
'mp4': 'video/mp4',
|
||||
'm4v': 'video/x-m4v',
|
||||
'mov': 'video/quicktime',
|
||||
'wmv': 'video/x-ms-wmv',
|
||||
'flv': 'video/x-flv',
|
||||
'avi': 'video/x-msvideo',
|
||||
'mkv': 'video/x-matroska',
|
||||
'm3u': 'application/x-mpegURL',
|
||||
'm3u8': 'application/vnd.apple.mpegurl',
|
||||
'ts': 'video/MP2T',
|
||||
'3gp': 'video/3gpp',
|
||||
'3g2': 'video/3gpp2',
|
||||
'mpd': 'video/vnd.mpeg.dash.mpd',
|
||||
'mp4': 'video/mp4',
|
||||
'webm': 'video/webm',
|
||||
'ogv': 'video/ogg',
|
||||
'ogm': 'video/ogg',
|
||||
'ogg': 'video/ogg',
|
||||
'ogx': 'application/ogg',
|
||||
'oga': 'audio/ogg',
|
||||
'spx': 'audio/ogg',
|
||||
'opus': 'audio/ogg',
|
||||
'flac': 'audio/flac'
|
||||
}
|
||||
|
||||
class WebServer:
|
||||
def __init__(self, ip, port, directory, site404="/404.html", event_handler=None, overwrites={}, custom_router=None):
|
||||
self.directory = directory
|
||||
self.ip = ip
|
||||
self.port = port
|
||||
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.s.bind((ip,port))
|
||||
self.threads = []
|
||||
self.running = True
|
||||
self.site404 = directory + "/404.html"
|
||||
self.event_handler = event_handler
|
||||
self.overwrites = overwrites
|
||||
self.custom_router = custom_router
|
||||
|
||||
def __getContentType(self, path):
|
||||
path = path.split(".")[-1]
|
||||
if not path in content_type.keys():
|
||||
return 'application/octet-stream'
|
||||
|
||||
return content_type[path]
|
||||
|
||||
def __getResponse(self, code, content_type, payload, custom_headers={}):
|
||||
|
||||
response = b'HTTP/1.1 ' + code.encode("utf-8") + b'\n'
|
||||
response += b'Content-Type: ' + content_type.encode("utf-8") + b'\n'
|
||||
response += b'Content-Length: ' + str(len(payload)).encode("utf-8") + b'\n'
|
||||
response += b'server: frmWrk\n'
|
||||
|
||||
for header_key in custom_headers.keys():
|
||||
response += header_key.encode("utf-8") + custom_headers[header_key].encode("utf-8") + b'\n'
|
||||
|
||||
response += b'\n'
|
||||
|
||||
response += payload + b'\n\n'
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def __get(self, path):
|
||||
# Remove data after the ?
|
||||
original = path
|
||||
|
||||
if ".." in path:
|
||||
return self.__getResponse("404 Not Found", self.__getContentType("/index.html"), b'')
|
||||
|
||||
if "?" in path:
|
||||
path = path[:path.index("?")]
|
||||
|
||||
if path == "/":
|
||||
path = "/index.html"
|
||||
|
||||
if os.path.isdir(self.directory + path):
|
||||
if path.endswith("/"):
|
||||
path = path + "/index.html"
|
||||
|
||||
else:
|
||||
return self.__getResponse("301 Moved Permanently", self.__getContentType("/index.html"), b'', custom_headers={"location: ": path + "/"})
|
||||
|
||||
if path in self.overwrites.keys():
|
||||
return self.__getResponse("200 OK", self.__getContentType(path), self.overwrites[path](original).encode("utf-8"))
|
||||
|
||||
path = self.directory + path
|
||||
|
||||
try:
|
||||
with open(path, "rb") as f:
|
||||
content = f.read()
|
||||
content_type = self.__getContentType(path)
|
||||
# if content_type.startswith("text/html"):
|
||||
# content = boron(content.decode('utf-8'), path).encode('utf-8')
|
||||
|
||||
return self.__getResponse("200 OK", content_type, content)
|
||||
|
||||
except FileNotFoundError:
|
||||
if "favicon.ico" in path:
|
||||
with open(os.path.dirname(os.path.abspath(__file__)) + "/favicon.ico", "rb") as f:
|
||||
content = f.read()
|
||||
return self.__getResponse("200 OK", "image/x-icon", content)
|
||||
|
||||
try:
|
||||
print(log_string("404 Not Found: " + path))
|
||||
with open(self.site404, "rb") as f:
|
||||
content = f.read()
|
||||
content_type = self.__getContentType(self.site404)
|
||||
return self.__getResponse("404 Not Found", content_type, content)
|
||||
|
||||
except FileNotFoundError:
|
||||
return self.__getResponse("404 Not Found", "text/html; charset=\"utf-8\"", AASCI_404_NOT_FOUND.encode("utf-8"))
|
||||
|
||||
|
||||
def __handleRequest(self, request):
|
||||
tokens = request.split(" ")
|
||||
method = tokens[0]
|
||||
path = tokens[1]
|
||||
version = tokens[2]
|
||||
|
||||
if self.event_handler:
|
||||
self.event_handler(method, (path))
|
||||
|
||||
if self.custom_router:
|
||||
return self.custom_router(method, path, {})
|
||||
|
||||
if method == "GET":
|
||||
return self.__get(path)
|
||||
|
||||
return "Only GET Requests Supported Yet Sorry."
|
||||
|
||||
def __handleClient(self, c: socket.socket, addr):
|
||||
global running
|
||||
while True and self.running:
|
||||
data = c.recv(1024)
|
||||
if not data:
|
||||
break
|
||||
|
||||
request = data.decode("utf-8")
|
||||
response = self.__handleRequest(request)
|
||||
|
||||
log_string(f"{addr} asked for {request.split(' ')[1]}")
|
||||
|
||||
c.send(response)
|
||||
|
||||
c.close()
|
||||
|
||||
def __startServer(self):
|
||||
global running, s
|
||||
|
||||
log_string("Server started on port " + str(self.port))
|
||||
|
||||
while self.running:
|
||||
try:
|
||||
c, addr = self.s.accept()
|
||||
p = threading.Thread(target=self.__handleClient, args=(c, addr))
|
||||
p.start()
|
||||
self.threads.append(p)
|
||||
except Exception as e:
|
||||
log_string(e)
|
||||
|
||||
|
||||
def start(self):
|
||||
print("Starting server...")
|
||||
self.s.listen(1)
|
||||
t = threading.Thread(target=self.__startServer)
|
||||
t.start()
|
||||
self.main_process = t
|
||||
|
||||
def close(self):
|
||||
self.running = False
|
||||
print("Closing server...")
|
||||
self.s.close()
|
||||
|
||||
for thread in self.threads:
|
||||
thread.join()
|
||||
|
||||
self.main_process.join()
|
||||
|
||||
print("Server closed")
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
import frmWrk.website
|
||||
|
||||
webserver = frmWrk.website.WebServer("127.0.0.1", 4000, "./")
|
||||
webserver.start()
|
|
@ -6,7 +6,7 @@
|
|||
margin-bottom: 1em;
|
||||
height: 80%;
|
||||
width: 30em;
|
||||
max-width: 30em;
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.search_bar {
|
||||
|
|
Loading…
Reference in a new issue