Compare commits

..

4 Commits

Author SHA1 Message Date
1fdc1d6ca9
[WIP] adding thumbnails 2024-09-28 21:36:04 +02:00
d55e036ca1
adding data directory to .gitignore 2024-07-03 20:53:48 +02:00
67060978ad
adding README.md 2024-07-03 20:41:01 +02:00
40c60514e7
adding requirements.txt & .gitignore 2024-07-03 20:38:10 +02:00
5 changed files with 70 additions and 1 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
venv
.idea
data

13
README.md Normal file
View 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)

View File

@ -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
View File

@ -0,0 +1,4 @@
PyYAML
pycryptodomex
aiohttp
thumbnail

View File

@ -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
@ -100,7 +117,7 @@ async def handle_upload(req):
os.mkdir(f'{conf.data_path}')
for _ in range(100):
hb = os.urandom(conf.url_hash_len//2)
hb = os.urandom(conf.url_hash_len // 2)
h = hb.hex()
if h not in file_db:
break
@ -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)