forked from Gardener/ShareX_Storage
Compare commits
No commits in common. "master" and "master" have entirely different histories.
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
venv
|
|
||||||
.idea
|
|
||||||
data
|
|
13
README.md
13
README.md
@ -1,13 +0,0 @@
|
|||||||
# 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,18 +27,3 @@ base_url: 'https://your-domain.net/f/'
|
|||||||
# Should file extensions be appended to the generated links.
|
# Should file extensions be appended to the generated links.
|
||||||
# Links always work with or without file extensions (like puush.me).
|
# Links always work with or without file extensions (like puush.me).
|
||||||
show_ext: True
|
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'
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
PyYAML
|
|
||||||
pycryptodomex
|
|
||||||
aiohttp
|
|
||||||
thumbnail
|
|
@ -10,16 +10,6 @@ from Cryptodome.Cipher import AES
|
|||||||
from Cryptodome.Util import Padding
|
from Cryptodome.Util import Padding
|
||||||
from aiohttp import web, hdrs
|
from aiohttp import web, hdrs
|
||||||
|
|
||||||
from thumbnail import generate_thumbnail
|
|
||||||
|
|
||||||
ThumbnailOptions = {
|
|
||||||
'trim': False,
|
|
||||||
'height': 300,
|
|
||||||
'width': 300,
|
|
||||||
'quality': 85,
|
|
||||||
'type': 'thumbnail'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class AppConfig:
|
class AppConfig:
|
||||||
_instance = None
|
_instance = None
|
||||||
@ -46,10 +36,6 @@ class AppConfig:
|
|||||||
self.show_ext = data.get('show_ext', True)
|
self.show_ext = data.get('show_ext', True)
|
||||||
self.max_filesize = data.get('max_filesize', '1024 ** 2 * 100') # Default 100 MB
|
self.max_filesize = data.get('max_filesize', '1024 ** 2 * 100') # Default 100 MB
|
||||||
self.base_url = data.get('base_url', 'http://localhost/f/')
|
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()
|
self.validate_config()
|
||||||
|
|
||||||
@ -66,9 +52,6 @@ class AppConfig:
|
|||||||
if not os.path.isdir(self.data_path):
|
if not os.path.isdir(self.data_path):
|
||||||
os.mkdir(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")}"
|
self.base_url = f"{self.base_url.strip("/ \t\r\n")}"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -117,7 +100,7 @@ async def handle_upload(req):
|
|||||||
os.mkdir(f'{conf.data_path}')
|
os.mkdir(f'{conf.data_path}')
|
||||||
|
|
||||||
for _ in range(100):
|
for _ in range(100):
|
||||||
hb = os.urandom(conf.url_hash_len // 2)
|
hb = os.urandom(conf.url_hash_len//2)
|
||||||
h = hb.hex()
|
h = hb.hex()
|
||||||
if h not in file_db:
|
if h not in file_db:
|
||||||
break
|
break
|
||||||
@ -136,11 +119,7 @@ async def handle_upload(req):
|
|||||||
c = AES.new(conf.del_crypt_key, AES.MODE_CBC)
|
c = AES.new(conf.del_crypt_key, AES.MODE_CBC)
|
||||||
hb = Padding.pad(hb, AES.block_size)
|
hb = Padding.pad(hb, AES.block_size)
|
||||||
del_h = (c.encrypt(hb) + c.iv).hex()
|
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}",'
|
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)
|
f'"delete_link":"{conf.base_url}/del/{del_h}"}}', status=200)
|
||||||
|
|
||||||
os.unlink(local_fname)
|
os.unlink(local_fname)
|
||||||
@ -190,18 +169,6 @@ 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():
|
def main():
|
||||||
for file in os.listdir(f"{conf.data_path}"):
|
for file in os.listdir(f"{conf.data_path}"):
|
||||||
try:
|
try:
|
||||||
@ -218,7 +185,6 @@ def main():
|
|||||||
app.router.add_post(base_path + '/post', handle_upload)
|
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 + '/del/{hash}', handle_delete)
|
||||||
app.router.add_get(base_path + '/{hash}', handle_download)
|
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)
|
web.run_app(app, port=80)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user