Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
1fdc1d6ca9 | |||
d55e036ca1 | |||
67060978ad | |||
40c60514e7 |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
venv
|
||||
.idea
|
||||
data
|
13
README.md
Normal file
13
README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# ShareX_Storage
|
||||
Simple tool to act as endpoint to upload files through ShareX to.
|
||||
|
||||
## Requirements
|
||||
* [PyYAML](https://pypi.org/project/PyYAML/)
|
||||
* [pycryptodomex](https://pypi.org/project/pycryptodomex/)
|
||||
* [aiohttp](https://pypi.org/project/aiohttp/)
|
||||
|
||||
+ [thumbnail](https://pypi.org/project/thumbnail/) (optional)
|
||||
+ [unoconv](https://github.com/unoconv/unoconv) (optional)
|
||||
+ [ffmpeg](https://www.ffmpeg.org/) (optional)
|
||||
+ [imagemagick](https://imagemagick.org/index.php) (optional)
|
||||
+ [curl](https://curl.se/) (optional)
|
15
config.yaml
15
config.yaml
@ -27,3 +27,18 @@ base_url: 'https://your-domain.net/f/'
|
||||
# Should file extensions be appended to the generated links.
|
||||
# Links always work with or without file extensions (like puush.me).
|
||||
show_ext: True
|
||||
|
||||
# Should a frontend to view and manage uploads be exposed?
|
||||
frontend: True
|
||||
|
||||
# Should thumbnails of uploaded files be created for frontend viewing.
|
||||
thumbnails: True
|
||||
|
||||
# Directory for storing thumbnails
|
||||
thumbnail_path: 'data/thumbs'
|
||||
|
||||
# Strategy for creating thumbnails. Possible values are:
|
||||
# on-upload: Creates a thumbnail when uploading a file.
|
||||
# on-request: Creates a thumbnail when requested by the frontend.
|
||||
# both: Creates a thumbnail on request if one hasn't been created on upload.
|
||||
thumbnail_strategy: 'both'
|
||||
|
4
requirements.txt
Normal file
4
requirements.txt
Normal file
@ -0,0 +1,4 @@
|
||||
PyYAML
|
||||
pycryptodomex
|
||||
aiohttp
|
||||
thumbnail
|
@ -10,6 +10,16 @@ from Cryptodome.Cipher import AES
|
||||
from Cryptodome.Util import Padding
|
||||
from aiohttp import web, hdrs
|
||||
|
||||
from thumbnail import generate_thumbnail
|
||||
|
||||
ThumbnailOptions = {
|
||||
'trim': False,
|
||||
'height': 300,
|
||||
'width': 300,
|
||||
'quality': 85,
|
||||
'type': 'thumbnail'
|
||||
}
|
||||
|
||||
|
||||
class AppConfig:
|
||||
_instance = None
|
||||
@ -36,6 +46,10 @@ class AppConfig:
|
||||
self.show_ext = data.get('show_ext', True)
|
||||
self.max_filesize = data.get('max_filesize', '1024 ** 2 * 100') # Default 100 MB
|
||||
self.base_url = data.get('base_url', 'http://localhost/f/')
|
||||
self.frontend = data.get('frontend', False)
|
||||
self.thumbnails = data.get('thumbnails', False)
|
||||
self.thumbnail_path = data.get('thumbnail_path', '/data/thumbs')
|
||||
self.thumbnail_strategy = data.get('thumbnail_strategy', 'both')
|
||||
|
||||
self.validate_config()
|
||||
|
||||
@ -52,6 +66,9 @@ class AppConfig:
|
||||
if not os.path.isdir(self.data_path):
|
||||
os.mkdir(self.data_path)
|
||||
|
||||
if not os.path.isdir(self.thumbnail_path):
|
||||
os.mkdir(self.thumbnail_path)
|
||||
|
||||
self.base_url = f"{self.base_url.strip("/ \t\r\n")}"
|
||||
|
||||
@staticmethod
|
||||
@ -119,7 +136,11 @@ async def handle_upload(req):
|
||||
c = AES.new(conf.del_crypt_key, AES.MODE_CBC)
|
||||
hb = Padding.pad(hb, AES.block_size)
|
||||
del_h = (c.encrypt(hb) + c.iv).hex()
|
||||
local_thname = f'{conf.thumbnail_path}/{h}_{filename}.png'
|
||||
generate_thumbnail(local_fname, local_thname, ThumbnailOptions)
|
||||
|
||||
return web.Response(text=f'{{"file_link":"{conf.base_url}/{h}{ext}",'
|
||||
f'"thumb_link":"{conf.base_url}/thumb/{h}{ext}",'
|
||||
f'"delete_link":"{conf.base_url}/del/{del_h}"}}', status=200)
|
||||
|
||||
os.unlink(local_fname)
|
||||
@ -169,6 +190,18 @@ async def handle_download(req):
|
||||
})
|
||||
|
||||
|
||||
async def handle_thumbnail(req):
|
||||
fhash = req.match_info.get('hash', '').split('.', 1)[0]
|
||||
if fhash not in file_db:
|
||||
return web.Response(text='file not found', status=404)
|
||||
|
||||
## TODO: If thumbnail doesn't exist, generate new thumbnail
|
||||
|
||||
return web.FileResponse(f"{conf.thumbnail_path}/{fhash}_{file_db[fhash]}", headers={
|
||||
hdrs.CONTENT_DISPOSITION: f'inline;filename="{file_db[fhash]}"'
|
||||
})
|
||||
|
||||
|
||||
def main():
|
||||
for file in os.listdir(f"{conf.data_path}"):
|
||||
try:
|
||||
@ -185,6 +218,7 @@ def main():
|
||||
app.router.add_post(base_path + '/post', handle_upload)
|
||||
app.router.add_get(base_path + '/del/{hash}', handle_delete)
|
||||
app.router.add_get(base_path + '/{hash}', handle_download)
|
||||
app.router.add_get(base_path + '/thumb/{hash}', handle_thumbnail)
|
||||
|
||||
web.run_app(app, port=80)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user