Update storage quota.
All checks were successful
RUpload build / Build (push) Successful in 1m5s

This commit is contained in:
retoor 2024-11-26 06:24:14 +01:00
parent 456e3c0823
commit e0fcf53788
8 changed files with 90 additions and 27 deletions

View File

@ -1,9 +1,8 @@
# RUpload
## About
Easiest way to upload files to a server.
Easiest file manager for your server made for public use.
Since it doesn't have captcha or whatsoever, it's only usable with people you trust on a not listed domain. It's destined for public use, as long the domain isn't listed in a search engine. It has a limitation for file size, so it would never go terribly wrong.
It doesn't have captcha or whatsoever. It's designed for public use, as long the domain isn't listed in a search engine. It has a limitation for file size, that's it's only security. Rate limiting is in consideration. The default file size is 50Mb. The default storage quota for whole directory is 10Gb. Default config will prevent your server for heavy abuse.
## Installation
```

Binary file not shown.

Binary file not shown.

View File

@ -12,10 +12,9 @@ Requires-Dist: dataset==1.6.2
# RUpload
## About
Easiest way to upload files to a server.
Easiest file manager for your server made for public use.
Since it doesn't have captcha or whatsoever, it's only usable with people you trust on a not listed domain. It's destined for public use, as long the domain isn't listed in a search engine. It has a limitation for file size, so it would never go terribly wrong.
It doesn't have captcha or whatsoever. It's designed for public use, as long the domain isn't listed in a search engine. It has a limitation for file size, that's it's only security. Rate limiting is in consideration. The default file size is 50Mb. The default storage quota for whole directory is 10Gb. Default config will prevent your server for heavy abuse.
## Installation
```

View File

@ -5,12 +5,26 @@ import pathlib
class Rupload(web.Application):
def __init__(self, upload_url:str="/uploads/", upload_path:str="uploads", max_file_size:int=1024*1024*50):
self.upload_path = upload_path
def __init__(
self,
upload_url: str = "/uploads/",
upload_path: str = "uploads",
max_file_size: int = 1024 * 1024 * 50,
upload_folder_quota: int = 10 * 1024 * 1024 * 1024,
):
self.upload_path = upload_path.rstrip("/")
self.max_file_size = max_file_size
self.upload_url = upload_url
self.upload_url = upload_url.rstrip("/")
self.upload_folder_quota = upload_folder_quota
super().__init__()
@property
def is_upload_folder_quota_reached(self):
return pathlib.Path(self.upload_path).stat().st_size > self.upload_folder_quota
def generate_upload_url(self, filename):
return self.upload_url + filename
UPLOAD_PAGE = """
<!DOCTYPE html>
@ -129,6 +143,7 @@ UPLOAD_PAGE = """
</html>
"""
def format_size(size):
if size < 1024:
return f"{size} B"
@ -141,13 +156,21 @@ def format_size(size):
else:
return f"{size / 1024 * 1024 * 1024 * 1024:.2f} TB"
def get_images(path):
images = []
for image in pathlib.Path(path).iterdir():
if image.is_file() and image.suffix in [".png", ".jpg", ".gif", ".jpeg", ".bmp"]:
if image.is_file() and image.suffix in [
".png",
".jpg",
".gif",
".jpeg",
".bmp",
]:
images.append(image)
return images
def get_files(path):
images = get_images(path)
files = []
@ -156,6 +179,7 @@ def get_files(path):
files.append(file)
return files
def create_images_html(url, image_paths):
images_html = ""
for image_path in image_paths:
@ -163,6 +187,7 @@ def create_images_html(url, image_paths):
images_html += f'<img class="thumbnail" src="{path}" alt="{image_path.name}">'
return images_html
def create_files_html(url, file_paths):
files_html = ""
for file_path in file_paths:
@ -170,7 +195,13 @@ def create_files_html(url, file_paths):
files_html += f'<a href="{path}">{file_path.name}</a> ({format_size(file_path.stat().st_size)})<br>'
return files_html
async def handle_upload(request: web.Request):
if request.app.is_upload_folder_quota_reached:
return web.HTTPFound(
"/?message=Server%20reached%20quota!%20Contact%20administrator."
)
reader = await request.multipart()
field = await reader.next()
app = request.app
@ -212,32 +243,55 @@ async def handle_upload(request:web.Request):
)
f.write(chunk)
print(f"File {filename} uploaded successfully.")
uploaded_url = app.upload_url.rstrip("/") + "/" + filename
uploaded_url = self.generate_upload_url(filename)
print(f"File {filename} is now available at: {uploaded_url}.")
return web.HTTPFound("/?message=File is succesfully uploaded and is available here:" + uploaded_url)
return web.HTTPFound(
"/?message=File is succesfully uploaded and is available here:"
+ uploaded_url
)
print("No file uploaded.")
return web.Response(status=400, text="No file uploaded.")
async def handle_index(request: web.Request):
image_paths = get_images(request.app.upload_path)
images_html = create_images_html(url=request.app.upload_url,image_paths=image_paths)
images_html = create_images_html(
url=request.app.upload_url, image_paths=image_paths
)
file_paths = get_files(request.app.upload_path)
files_html = create_files_html(url=request.app.upload_url, file_paths=file_paths)
html_content = UPLOAD_PAGE.replace("[images_html]", images_html)
html_content = html_content.replace("[files_html]", files_html)
message = request.query.get("message", "")
if request.app.is_upload_folder_quota_reached:
message = "Server reached quota! Contact administrator."
if request.app.upload_url in message:
url = message[message.find(request.app.upload_url) :]
message = message.replace(request.app.upload_url, f" <a href=\"{url}")
message += f"\">{url}</a>"
message = message.replace(request.app.upload_url, f' <a href="{url}')
message += f'">{url}</a>'
if message:
message += "<br /><br />"
html_content = html_content.replace("[message]", message)
return web.Response(text=html_content, content_type="text/html")
def create_app(upload_url:str="/", upload_path:str="upload", max_file_size:int=1024 * 1024 * 50):
app = Rupload(upload_url=upload_url, upload_path=upload_path, max_file_size=max_file_size)
app.add_routes([web.get("/", handle_index), web.post("/upload", handle_upload),web.static("/uploads", "uploads")])
def create_app(
upload_url: str = "/",
upload_path: str = "upload",
max_file_size: int = 1024 * 1024 * 50,
upload_folder_quota: int = 10 * 1024 * 1024 * 1024,
):
app = Rupload(
upload_url=upload_url,
upload_path=upload_path,
max_file_size=max_file_size,
upload_folder_quota=upload_folder_quota,
)
app.add_routes(
[
web.get("/", handle_index),
web.post("/upload", handle_upload),
web.static("/uploads", "uploads"),
]
)
return app

View File

@ -29,12 +29,23 @@ def parse_args():
default=50 * 1024 * 1024,
help="Maximum file size in bytes (default is 50MB).",
)
parser.add_argument(
"--upload_folder_quota",
type=int,
default=10 * 1024 * 1024 * 1024,
help="Quata upload folder in bytes (default is 10GB).",
)
return parser.parse_args()
def main():
args = parse_args()
app = create_app(upload_url=args.upload_url, upload_path=args.upload_folder, max_file_size=args.max_file_size)
app = create_app(
upload_url=args.upload_url,
upload_path=args.upload_folder,
max_file_size=args.max_file_size,
upload_folder_quota=args.upload_folder_quota,
)
web.run_app(app, host=args.hostname, port=args.port)