This commit is contained in:
Dagger 2022-06-13 14:29:13 -04:00
parent c59d31ca5b
commit 10f04c9315
12 changed files with 274 additions and 0 deletions

16
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,16 @@
build-test:
image: python:3.9
script:
- python --version
- pip --version
- pip install -r requirements.txt
- echo "pytest needs finishing"
build-docker:
image: docker
services:
- docker:dind
script:
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin
- docker build -t $CI_REGISTRY_IMAGE .
- docker push $CI_REGISTRY_IMAGE

47
app.py Normal file
View File

@ -0,0 +1,47 @@
from fastapi import FastAPI, File, UploadFile, Form, Request
from fastapi.staticfiles import StaticFiles
from starlette.templating import Jinja2Templates
import shutil
import models
description = """
Oki.cx is a API for uploading file to a Server to be shared via HTTP.
## Response Types
- HTML Response
- JSON Response
"""
app = FastAPI(
title="Oki.cx - Fileshare",
description=description,
version="0.1",
terms_of_service="http://oki.cx/fileshare/tos",
contact={
"name": "oki.cx",
"email": "cody@oki.cx",
},
license_info={
"name": "MIT License",
"url": "https://gitlab.oki.cx/mrpvtdagger/oki.cx-fileshare/-/raw/main/LICENSE",
},
)
templates = Jinja2Templates(directory="templates")
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/", include_in_schema=False)
def home(request: Request):
return templates.TemplateResponse("base.html",{"request": request, "is_hidden": "is-hidden"})
@app.post("/upload/{response_type}")
def file(request: Request, response_type: str, file: UploadFile = File(...)):
uploaded_file = models.UploadFile(file, file.filename, file.content_type)
if response_type.lower == "json":
return uploaded_file
else:
return templates.TemplateResponse("html_response.html",{"request": request, "uploaded_file": uploaded_file, "filename": file.filename})

19
models.py Normal file
View File

@ -0,0 +1,19 @@
import random
import string
import os
import shutil
def UploadFile(file, filename, content_type):
def randmname(size=6, chars=string.ascii_lowercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
split_filename = filename.split('.')
rand_filename = f"{randmname(25)}.{split_filename[1]}"
with open(f'files/{rand_filename}','wb',100*(2**20)) as buffer:
shutil.copyfileobj(file.file, buffer)
cdn_info = {
"url" : f"https://cdn.oki.cx/files/{rand_filename}",
"content_type" : content_type
}
return cdn_info

BIN
requirements.txt Normal file

Binary file not shown.

View File

@ -0,0 +1,15 @@
#particles-js {
position: absolute;
width: 100%;
height: 100%;
background: rgb(21, 16, 25);
}
a, a:visited {
color: rgb(136, 200, 255);
transition: 0.25s;
}
a:hover, a:focus {
color: rgb(18, 144, 255);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
static/img/fav.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 898 B

106
static/js/background.js Normal file
View File

@ -0,0 +1,106 @@
// ParticlesJS Config.
particlesJS("particles-js", {
"particles": {
"number": {
"value": 100,
"density": {
"enable": true,
"value_area": 700
}
},
"color": {
"value": "#91c9ff"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
"polygon": {
"nb_sides": 5
},
},
"opacity": {
"value": 0.5,
"random": false,
"anim": {
"enable": false,
"speed": 0.1,
"opacity_min": 0.1,
"sync": false
}
},
"size": {
"value": 3,
"random": true,
"anim": {
"enable": false,
"speed": 10,
"size_min": 0.1,
"sync": false
}
},
"line_linked": {
"enable": true,
"distance": 150,
"color": "#91c9ff",
"opacity": 0.4,
"width": 1
},
"move": {
"enable": true,
"speed": 1,
"direction": "none",
"random": false,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 1200
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": false,
"mode": "grab"
},
"onclick": {
"enable": false,
"mode": "push"
},
"resize": true
},
"modes": {
"grab": {
"distance": 140,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 400,
"size": 40,
"duration": 2,
"opacity": 8,
"speed": 3
},
"repulse": {
"distance": 200,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
});

1
static/js/htmx.js Normal file

File diff suppressed because one or more lines are too long

9
static/js/particles.min.js vendored Normal file

File diff suppressed because one or more lines are too long

58
templates/base.html Normal file
View File

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="shortcut icon" type="image/x-icon" href="../static/img/fav-icon-256x256.ico">
<title>Oki.cx - File Share</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css">
<link rel="stylesheet" href="../static/css/style-custom.css">
<script src="https://unpkg.com/htmx.org@1.7.0"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.5"></script>
<script src="//code.iconify.design/1/1.0.6/iconify.min.js"></script>
</head>
<body>
<div id="particles-js"></div>
<div class="container">
<div class="padding p-4 has-text-centered">
<p class="title has-text-white is-1">Oki.cx File Share</p>
<p class="subtitle has-text-white is-4">Free and <a href="https://gitlab.oki.cx/mrpvtdagger/oki.cx-fileshare">Open Source <span class="iconify" data-icon="mdi-gitlab"></span> </a></br> With a <a href="/docs">API</a></br><strong class="has-text-white">Personal use only!</strong></p>
</div>
<section class="section">
<div class="container">
<div class="columns is-centered">
<div class="column is-half">
<form hx-encoding='multipart/form-data' hx-post='/upload/html'
_='on htmx:xhr:progress(loaded, total) set #progress.value to (loaded/total)*100'>
<div class="file is-boxed is-centered">
<label class="file-label">
<input class="file-input" type="file" name="file" hx-post="/upload/html" hx-trigger="change" hx-swap="afterend" hx-target="#upload-resault">
<span class="file-cta">
<span class="file-icon">
<span class="iconify" data-icon="fa:upload"></span>
</span>
<span class="file-label">
Select or Drag File(s)
</span>
</span>
</label>
</div>
</form>
</div>
</div>
</div>
<div class="container">
<div class="columns is-centered">
<div class="column is-two-fifths">
<progress id="progress" class="progress is-info" value="1" max="100"></progress>
<div id="upload-resault"></div>
</div>
</div>
</div>
<p class="padding p-4 subtitle is-7 has-text-white has-text-centered">By clicking <strong class="has-text-link">"upload"</strong> you agree to using this for personal use only</a>.</p>
</section>
<!-- scripts -->
<script src="../static/js/particles.min.js"></script>
<script src="../static/js/background.js"></script>
</body>
</html>

View File

@ -0,0 +1,3 @@
<div>
<a href="{{uploaded_file['url']}}">{{filename}}</a> <span class="iconify" data-icon="icon-park:check-one"></span>
</div>