Compare commits
88
Commits
1ed30e0d80
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15612eab4c | ||
|
|
949e7b84f7 | ||
|
|
5015e64bd2 | ||
|
|
ecf2aa0527 | ||
|
|
c551e69bb6 | ||
|
|
22ed8844b9 | ||
|
|
81b8825884 | ||
|
|
65f596c51c | ||
|
|
879a42039d | ||
|
|
1747045941 | ||
|
|
85fec57bb7 | ||
|
|
0516bd4a5f | ||
|
|
05b70cf94e | ||
|
|
f08844193b | ||
|
|
e389d81aeb | ||
|
|
629439043d | ||
|
|
201a78c963 | ||
|
|
458b98a870 | ||
|
|
92d855dd2a | ||
|
|
5ce5796abb | ||
|
|
6470e170f1 | ||
|
|
b1d1974704 | ||
|
|
5a2dd5f926 | ||
|
|
118140ca55 | ||
|
|
ebad87c5d1 | ||
|
|
4821bae92f | ||
|
|
387a8dc9cd | ||
|
|
d7ab7ddb13 | ||
|
|
40fa720ad9 | ||
|
|
a550667378 | ||
|
|
8317958a0f | ||
|
|
d564093193 | ||
|
|
ab304d82dc | ||
|
|
da7fa63169 | ||
|
|
1a60bd02ad | ||
|
|
bda8470f67 | ||
|
|
400cc1dc52 | ||
|
|
2fa7c04898 | ||
|
|
2e2d02340a | ||
|
|
ef93230bed | ||
|
|
3a000f2ce5 | ||
|
|
5ce5a9ede3 | ||
|
|
68828686bf | ||
|
|
d345030f86 | ||
|
|
33e0155031 | ||
|
|
f6e41aa002 | ||
|
|
e691bf5a18 | ||
|
|
5570ecacb2 | ||
|
|
1cab3d2147 | ||
|
|
02dd36aa06 | ||
|
|
38d935f8ad | ||
|
|
2bcf2dc990 | ||
|
|
f70f2854e1 | ||
|
|
0d16afae00 | ||
|
|
1f43d61524 | ||
|
|
aeb54beb27 | ||
|
|
f8c3fbee7d | ||
|
|
53925dab2c | ||
|
|
0c594872bc | ||
|
|
bd5f0bd042 | ||
|
|
934387860a | ||
|
|
b67024ab06 | ||
|
|
bff6baaa45 | ||
|
|
87ebae5a79 | ||
|
|
c2394502b5 | ||
|
|
009b2ad475 | ||
|
|
9defb4e1b2 | ||
|
|
ad8cbe211c | ||
|
|
b97c05ceb8 | ||
|
|
351934b9ed | ||
|
|
0dcb3f0d45 | ||
|
|
bcb18e8195 | ||
|
|
ee4d3dfd47 | ||
|
|
a280f5dec7 | ||
|
|
098b70fd09 | ||
|
|
1aa4712a86 | ||
|
|
d6e684a58c | ||
|
|
462b7ebdee | ||
|
|
fb327d2f9b | ||
|
|
206d4ff6a6 | ||
|
|
836f809df4 | ||
|
|
c736af6835 | ||
|
|
42e48271e2 | ||
|
|
ab5d3d6333 | ||
|
|
ccd9edf566 | ||
|
|
45ce49c246 | ||
|
|
57a9a89cd8 | ||
|
|
b5d889c478 |
@@ -0,0 +1,30 @@
|
|||||||
|
name: RUpload build
|
||||||
|
run-name: RUpload build
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: List files in the repository
|
||||||
|
run: |
|
||||||
|
ls ${{ gitea.workspace }}
|
||||||
|
- run: echo "Install dependencies."
|
||||||
|
- run: apt update
|
||||||
|
- run: apt install python3 python3-pip python3-venv make -y
|
||||||
|
- run: echo "Create environment."
|
||||||
|
- run: make ensure_env
|
||||||
|
- run: echo "Create build."
|
||||||
|
- run: make build
|
||||||
|
- run: echo "Install package."
|
||||||
|
- run: make install
|
||||||
|
- run: echo "Test installation."
|
||||||
|
- run: ./.venv/bin/rupload.serve --help
|
||||||
|
- run: git add .
|
||||||
|
- run: git config --global user.email "bot@molodetz.com"
|
||||||
|
- run: git config --global user.name "bot"
|
||||||
|
- run: git commit -a -m "Update build files."
|
||||||
|
- run: git push
|
||||||
|
- run: echo "This job's status is ${{ job.status }}."
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
.history
|
.history
|
||||||
.venv
|
.venv
|
||||||
src/upload/__pycache__
|
src/rupload/__pycache__
|
||||||
|
uploads/*
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
all: ensure_env clean build serve
|
all: clean ensure_env build install serve
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-@rm -rf src/rupload/__pycache__
|
-@rm -rf src/rupload/__pycache__
|
||||||
@@ -9,6 +9,8 @@ ensure_env:
|
|||||||
build:
|
build:
|
||||||
./.venv/bin/python -m pip install build
|
./.venv/bin/python -m pip install build
|
||||||
./.venv/bin/python -m build .
|
./.venv/bin/python -m build .
|
||||||
|
|
||||||
|
install:
|
||||||
./.venv/bin/python -m pip install -e .
|
./.venv/bin/python -m pip install -e .
|
||||||
|
|
||||||
serve:
|
serve:
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
# RUpload
|
# RUpload
|
||||||
|
|
||||||
## About
|
Easiest file manager for your server made for public use.
|
||||||
Easiest way to upload files to a server.
|
|
||||||
|
|
||||||
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
|
## Installation
|
||||||
```
|
1. `make ensure_venv`
|
||||||
python3 -m venv .venv
|
2. `make install`
|
||||||
./venv/bin/python -m pip install .
|
3. `source ./.venv/bin/activate`
|
||||||
```
|
4. `rupload.serve` (See parameters below. Running with default config using no parameters works too.)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
@@ -16,6 +16,7 @@ python_requires = >=3.7
|
|||||||
install_requires =
|
install_requires =
|
||||||
aiohttp==3.10.10
|
aiohttp==3.10.10
|
||||||
dataset==1.6.2
|
dataset==1.6.2
|
||||||
|
pillow
|
||||||
|
|
||||||
[options.packages.find]
|
[options.packages.find]
|
||||||
where = src
|
where = src
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Metadata-Version: 2.1
|
Metadata-Version: 2.4
|
||||||
Name: rupload
|
Name: rupload
|
||||||
Version: 1.3.37
|
Version: 1.3.37
|
||||||
Summary: upload tool
|
Summary: upload tool
|
||||||
@@ -9,21 +9,47 @@ Requires-Python: >=3.7
|
|||||||
Description-Content-Type: text/markdown
|
Description-Content-Type: text/markdown
|
||||||
Requires-Dist: aiohttp==3.10.10
|
Requires-Dist: aiohttp==3.10.10
|
||||||
Requires-Dist: dataset==1.6.2
|
Requires-Dist: dataset==1.6.2
|
||||||
|
Requires-Dist: pillow
|
||||||
|
|
||||||
# RUpload
|
# RUpload
|
||||||
|
|
||||||
## About
|
Easiest file manager for your server made for public use.
|
||||||
Easiest way to upload files to a server.
|
|
||||||
|
|
||||||
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
|
## Installation
|
||||||
```
|
1. `make ensure_venv`
|
||||||
python3 -m venv .venv
|
2. `make install`
|
||||||
./venv/bin/python -m pip install .
|
3. `source ./.venv/bin/activate`
|
||||||
```
|
4. `rupload.serve` (See parameters below. Running with default config using no parameters works too.)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
```
|
```bash
|
||||||
rupload.serve [host(127.0.0.1)] [port] [destination path for uploads] [max file size in bytes]
|
rupload.serve [-h]
|
||||||
|
[--hostname HOSTNAME]
|
||||||
|
[--port PORT]
|
||||||
|
[--upload_folder UPLOAD_FOLDER]
|
||||||
|
[--upload_url UPLOAD_URL]
|
||||||
|
[--max_file_size MAX_FILE_SIZE]
|
||||||
|
|
||||||
|
Start the file upload server.
|
||||||
|
|
||||||
|
options:
|
||||||
|
-h, --help show this help message
|
||||||
|
and exit
|
||||||
|
--hostname HOSTNAME The hostname for the
|
||||||
|
server.
|
||||||
|
--port PORT The port to bind the
|
||||||
|
server to.
|
||||||
|
--upload_folder UPLOAD_FOLDER
|
||||||
|
Directory to store
|
||||||
|
uploaded files.
|
||||||
|
--upload_url UPLOAD_URL
|
||||||
|
HTTP(S) URL where the
|
||||||
|
server will serve the
|
||||||
|
uploaded files.
|
||||||
|
--max_file_size MAX_FILE_SIZE
|
||||||
|
Maximum file size in
|
||||||
|
bytes (default is
|
||||||
|
50MB).
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
aiohttp==3.10.10
|
aiohttp==3.10.10
|
||||||
dataset==1.6.2
|
dataset==1.6.2
|
||||||
|
pillow
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+134
-36
@@ -1,33 +1,56 @@
|
|||||||
import aiohttp
|
|
||||||
from aiohttp import web
|
|
||||||
import asyncio
|
|
||||||
import pathlib
|
import pathlib
|
||||||
|
|
||||||
|
from aiohttp import web
|
||||||
|
|
||||||
|
MAX_FILE_SIZE = 1024 * 1024 * 300 # 50Mb
|
||||||
|
UPLOAD_FOLDER_QUOTA = 10 * 1024 * 1024 * 1024 # 10Gb
|
||||||
|
UPLOAD_URL = "/"
|
||||||
|
UPLOAD_PATH = "uploads"
|
||||||
|
|
||||||
|
|
||||||
class Rupload(web.Application):
|
class Rupload(web.Application):
|
||||||
def __init__(self, upload_url:str="/uploads/", upload_path:str="uploads", max_file_size:int=1024*1024*50):
|
def __init__(
|
||||||
self.upload_path = upload_path
|
self,
|
||||||
|
upload_url: str = UPLOAD_URL,
|
||||||
|
upload_path: str = UPLOAD_PATH,
|
||||||
|
max_file_size: int = MAX_FILE_SIZE,
|
||||||
|
upload_folder_quota: int = UPLOAD_FOLDER_QUOTA,
|
||||||
|
):
|
||||||
|
self.upload_path = upload_path.rstrip("/")
|
||||||
self.max_file_size = max_file_size
|
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__()
|
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 = """
|
UPLOAD_PAGE = """
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=0.9">
|
||||||
<title>File Upload</title>
|
<title>RUpload 1.33.7</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: "Courier New", Courier, monospace;
|
||||||
background-color: #f4f4f9;
|
background-color: #111111;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
word-break: break-all;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@@ -38,7 +61,10 @@ UPLOAD_PAGE = """
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
.container-images {
|
||||||
|
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
@@ -47,6 +73,7 @@ UPLOAD_PAGE = """
|
|||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
color: #333;
|
color: #333;
|
||||||
clear: both;
|
clear: both;
|
||||||
@@ -96,8 +123,9 @@ UPLOAD_PAGE = """
|
|||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
margin: 10px;
|
margin: 3px;
|
||||||
float:left;
|
float:left;
|
||||||
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -112,9 +140,9 @@ UPLOAD_PAGE = """
|
|||||||
<button type="submit">Upload</button>
|
<button type="submit">Upload</button>
|
||||||
</form>
|
</form>
|
||||||
<br />
|
<br />
|
||||||
Click <a href="#files">here</a> to see <a href="#files">uploaded files</a> (non-image) at the bottom of this page.<br />
|
Click <a href="#files">here</a> to see <a href="#files">uploaded files</a> (non-image) at the bottom of this page.
|
||||||
<h2>Uploaded images:</h2>
|
<h2>Uploaded images:</h2>
|
||||||
<div class="container-image">
|
<div class="container-images">
|
||||||
[images_html]
|
[images_html]
|
||||||
</div>
|
</div>
|
||||||
<h2 id="files">Uploaded files:</h2>
|
<h2 id="files">Uploaded files:</h2>
|
||||||
@@ -129,6 +157,7 @@ UPLOAD_PAGE = """
|
|||||||
</html>
|
</html>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def format_size(size):
|
def format_size(size):
|
||||||
if size < 1024:
|
if size < 1024:
|
||||||
return f"{size} B"
|
return f"{size} B"
|
||||||
@@ -141,13 +170,23 @@ def format_size(size):
|
|||||||
else:
|
else:
|
||||||
return f"{size / 1024 * 1024 * 1024 * 1024:.2f} TB"
|
return f"{size / 1024 * 1024 * 1024 * 1024:.2f} TB"
|
||||||
|
|
||||||
|
|
||||||
def get_images(path):
|
def get_images(path):
|
||||||
images = []
|
images = []
|
||||||
for image in pathlib.Path(path).iterdir():
|
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.lower() in [
|
||||||
|
".png",
|
||||||
|
".jpg",
|
||||||
|
".gif",
|
||||||
|
".jpeg",
|
||||||
|
".bmp",
|
||||||
|
".webp",
|
||||||
|
".svg",
|
||||||
|
]:
|
||||||
images.append(image)
|
images.append(image)
|
||||||
return images
|
return images
|
||||||
|
|
||||||
|
|
||||||
def get_files(path):
|
def get_files(path):
|
||||||
images = get_images(path)
|
images = get_images(path)
|
||||||
files = []
|
files = []
|
||||||
@@ -156,21 +195,30 @@ def get_files(path):
|
|||||||
files.append(file)
|
files.append(file)
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
|
||||||
def create_images_html(url, image_paths):
|
def create_images_html(url, image_paths):
|
||||||
images_html = ""
|
images_html = ""
|
||||||
for image_path in image_paths:
|
for image_path in image_paths:
|
||||||
path = url.rstrip("/") + "/" + image_path.name
|
path = url.rstrip("/") + "/" + image_path.name
|
||||||
images_html += f'<img class="thumbnail" src="{path}" alt="{image_path.name}">'
|
thumbnail_path = "/thumbnail/" + url.strip("/") + "/" + image_path.name
|
||||||
|
images_html += f'<a href="{path}"><img class="thumbnail" src="{thumbnail_path}" alt="{image_path.name}" /></a>\n'
|
||||||
return images_html
|
return images_html
|
||||||
|
|
||||||
|
|
||||||
def create_files_html(url, file_paths):
|
def create_files_html(url, file_paths):
|
||||||
files_html = ""
|
files_html = ""
|
||||||
for file_path in file_paths:
|
for file_path in file_paths:
|
||||||
path = url.rstrip("/") + "/" + file_path.name
|
path = url.rstrip("/") + "/" + file_path.name
|
||||||
files_html += f'<a href="{path}">{file_path.name}</a> ({format_size(file_path.stat().st_size)})<br>'
|
files_html += f'<a href="{path}">{file_path.name}</a> ({format_size(file_path.stat().st_size)})\n<br>\n'
|
||||||
return files_html
|
return files_html
|
||||||
|
|
||||||
async def handle_upload(request:web.Request):
|
|
||||||
|
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()
|
reader = await request.multipart()
|
||||||
field = await reader.next()
|
field = await reader.next()
|
||||||
app = request.app
|
app = request.app
|
||||||
@@ -206,38 +254,88 @@ async def handle_upload(request:web.Request):
|
|||||||
print(f"File {filename} deleted.")
|
print(f"File {filename} deleted.")
|
||||||
return web.Response(
|
return web.Response(
|
||||||
status=413,
|
status=413,
|
||||||
text="File is too large. Maximum file size is {} bytes.".format(
|
text=f"File is too large. Maximum file size is {app.max_file_size} bytes.",
|
||||||
app.max_file_size
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
print(f"File {filename} uploaded successfully.")
|
print(f"File {filename} uploaded successfully.")
|
||||||
uploaded_url = app.upload_url.rstrip("/") + "/" + filename
|
uploaded_url = request.app.generate_upload_url(filename)
|
||||||
print(f"File {filename} is now available at: {uploaded_url}.")
|
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.")
|
print("No file uploaded.")
|
||||||
return web.Response(status=400, text="No file uploaded.")
|
return web.Response(status=400, text="No file uploaded.")
|
||||||
|
|
||||||
|
|
||||||
async def handle_index(request:web.Request):
|
async def handle_thumbnail(request: web.Request):
|
||||||
|
path = request.match_info["path"]
|
||||||
|
|
||||||
|
safe_path = pathlib.Path(request.app.upload_path).joinpath(pathlib.Path(path).name)
|
||||||
|
|
||||||
|
if not safe_path.is_file():
|
||||||
|
return web.Response(status=400, text="Invalid file type.")
|
||||||
|
|
||||||
|
|
||||||
|
thumbnail_path = pathlib.Path(request.app.upload_path).joinpath(".thumbnail").joinpath(pathlib.Path(safe_path).name)
|
||||||
|
if not thumbnail_path.parent.exists():
|
||||||
|
thumbnail_path.parent.mkdir(exist_ok=True,parents=False)
|
||||||
|
|
||||||
|
if not thumbnail_path.exists():
|
||||||
|
from PIL import Image
|
||||||
|
image = Image.open(safe_path)
|
||||||
|
image.thumbnail((200, 200))
|
||||||
|
image.save(thumbnail_path)
|
||||||
|
|
||||||
|
return web.FileResponse(thumbnail_path)
|
||||||
|
|
||||||
|
async def handle_index(request: web.Request):
|
||||||
image_paths = get_images(request.app.upload_path)
|
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)
|
file_paths = get_files(request.app.upload_path)
|
||||||
files_html = create_files_html(url=request.app.upload_url,file_paths=file_paths)
|
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 = UPLOAD_PAGE.replace("[images_html]", images_html)
|
||||||
html_content = html_content.replace("[files_html]",files_html)
|
html_content = html_content.replace("[files_html]", files_html)
|
||||||
message = request.query.get("message", "")
|
message = request.query.get("message", "")
|
||||||
if request.app.upload_url in message:
|
if request.app.is_upload_folder_quota_reached:
|
||||||
url = message[message.find(request.app.upload_url):]
|
message = "Server reached quota! Contact administrator."
|
||||||
message = message.replace(request.app.upload_url, f" <a href=\"{url}")
|
if "is available here: " in message:
|
||||||
message += f"\">{url}</a>"
|
url = message[message.find("here: ") + len("here: ") :]
|
||||||
|
message = message[: message.find("here: ") + len("here: ")]
|
||||||
|
message += f'<a href="{url}">'
|
||||||
|
message += f"{url}</a>"
|
||||||
|
if not message:
|
||||||
|
message = (
|
||||||
|
"Any file type is allowed thus also binary/executable or source files."
|
||||||
|
)
|
||||||
if message:
|
if message:
|
||||||
message += "<br /><br />"
|
message += "<br /><br />"
|
||||||
html_content = html_content.replace("[message]",message)
|
html_content = html_content.replace("[message]", message)
|
||||||
return web.Response(text=html_content, content_type="text/html")
|
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):
|
def create_app(
|
||||||
app = Rupload(upload_url=upload_url, upload_path=upload_path, max_file_size=max_file_size)
|
upload_url: str = UPLOAD_URL,
|
||||||
app.add_routes([web.get("/", handle_index), web.post("/upload", handle_upload),web.static("/uploads", "uploads")])
|
upload_path: str = UPLOAD_PATH,
|
||||||
|
max_file_size: int = MAX_FILE_SIZE,
|
||||||
|
upload_folder_quota: int = UPLOAD_FOLDER_QUOTA,
|
||||||
|
):
|
||||||
|
app = Rupload(
|
||||||
|
upload_url=upload_url,
|
||||||
|
upload_path=upload_path,
|
||||||
|
max_file_size=max_file_size,
|
||||||
|
upload_folder_quota=upload_folder_quota,
|
||||||
|
)
|
||||||
|
pathlib.Path(upload_path).mkdir(parents=True, exist_ok=True)
|
||||||
|
app.add_routes(
|
||||||
|
[
|
||||||
|
web.get("/", handle_index),
|
||||||
|
web.post("/upload", handle_upload),
|
||||||
|
web.static("/", upload_path),
|
||||||
|
web.get("/thumbnail/{path:.*}", handle_thumbnail),
|
||||||
|
web.static("/uploads", upload_path),
|
||||||
|
]
|
||||||
|
)
|
||||||
return app
|
return app
|
||||||
|
|||||||
+14
-1
@@ -1,5 +1,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
|
|
||||||
from rupload.app import create_app
|
from rupload.app import create_app
|
||||||
|
|
||||||
|
|
||||||
@@ -29,12 +31,23 @@ def parse_args():
|
|||||||
default=50 * 1024 * 1024,
|
default=50 * 1024 * 1024,
|
||||||
help="Maximum file size in bytes (default is 50MB).",
|
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()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = parse_args()
|
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)
|
web.run_app(app, host=args.hostname, port=args.port)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user