pyshare/pyshare.py

183 lines
5.8 KiB
Python
Executable File

#!/usr/bin/env python
from string import ascii_letters, digits
from argparse import ArgumentParser
from pysftp import Connection
from subprocess import call
from random import choices
from PIL import Image
import pyperclip
import config
import sys
import os
import re
character_pool = ascii_letters + digits
def parse_arguments():
parser = ArgumentParser()
parser.add_argument('-m' '--mode', type=str, dest='mode', default='screenshot',
help='Sets the input mode. Allowed values are "screenshot" and "clipboard". Implicit it file(s) are set.')
parser.add_argument('-f', '--files', type=str, nargs='*', dest='files', help='List of files to be uploaded')
return parser.parse_args()
def generate_filename(length, ext, prefix=''):
return prefix + ''.join(choices(character_pool, k=length)) + '.' + ext
def find_valid_filename(prefix, length, ext, conn):
filename = generate_filename(prefix=prefix, length=length, ext=ext)
i = 0
while conn.exists(filename):
filename = generate_filename(length=length, ext=ext, prefix=prefix)
i += 1
if i > 1000:
# completely, definitely, totally justified recursion... yay?
return find_valid_filename(prefix, length + 1, ext, conn)
return filename
def upload_local_file(path: str) -> str:
if config.uploader in ['ftp', 'sftp']:
filename = ftp_upload(path)[1]
return config.url_template.format(filename)
else:
return curl_upload(path)
def take_screenshot() -> None:
tempname = generate_filename(config.length, 'png')
file = os.path.join(config.local_directory, tempname)
call(['maim', '-s', file])
ftp_upload(ext='png', sourcefile=file, mode='screenshot')
if not config.keep_local_copies:
os.remove(file)
def ftp_upload(sourcefile, *, mode=None, ext=None) -> tuple:
if ext is None:
# TODO files without extension
exts = {
'screenshot': 'png',
'text': 'txt',
}
if re.search('\.tar\.\w{1,4}]', sourcefile):
# properly handle .tar.something files
ext = sourcefile.split('.')[-2:]
else:
ext = exts.get(mode, mode not in exts and sourcefile.split('.')[-1]) # Only do the split if necessary
with Connection(config.sftp_address, username=config.username, password=config.password,
private_key=config.private_key, private_key_pass=config.private_key_pass) as conn:
conn.chdir(config.remote_directory)
os.chdir(config.local_directory)
cur_name = sourcefile.split('/')[-1]
filename = cur_name
if mode == 'screenshot':
if conn.exists(cur_name):
filename = find_valid_filename(prefix=config.prefix, length=config.length, ext=ext, conn=conn)
conn.put(filename, filename)
else:
filename = find_valid_filename(prefix=config.prefix, length=config.length, ext=ext, conn=conn)
if mode == 'file':
conn.put(sourcefile, filename)
fullpath = os.path.join(config.local_directory, filename)
notify_user(config.url_template.format(filename))
return fullpath, filename
def curl_upload(filename):
return call(config.custom_curl_command)
def notify_user(url, image=None):
print(url)
pyperclip.copy(url)
if image:
img = Image.open(image)
img.thumbnail((384, 384), Image.ANTIALIAS)
thumbnail = os.path.join(config.local_directory, 'thumb.jpg')
img.save(thumbnail)
call(['notify-send', '-a pyshare', url, f'-i {thumbnail}', '-t 3000'])
os.remove(thumbnail)
else:
call(['notify-send', '-a pyshare', url, '-t 3000'])
def parse_text(args):
text = pyperclip.paste()
if re.match(r'(https?|s?ftp)://', text):
mirror_file(text)
elif os.path.isfile(text):
upload_local_file(text)
else:
upload_text(text)
def mirror_file(text):
os.chdir(config.local_directory)
call(['wget', text])
filename = text.rsplit('/', 1)[1]
url = upload_local_file(os.path.join(config.local_directory, filename))
os.remove(os.path.join(config.local_directory, filename))
notify_user(url)
def upload_text(text):
filename = generate_filename(config.length, 'txt')
with open(os.path.join(config.local_directory, filename), 'w') as file:
file.write(text)
url = upload_local_file(os.path.join(config.local_directory, filename))
os.remove(os.path.join(config.local_directory, filename))
notify_user(url)
if __name__ == '__main__':
args = parse_arguments()
if args.mode == 'screenshot':
take_screenshot()
elif args.mode == 'clipboard':
parse_text(pyperclip.paste())
else:
for file in args.files:
upload_local_file(file)
"""
if config.uploader in ['ftp', 'sftp']:
if args.files is not None:
for file in args.files:
upload_local_file(file)
elif args.mode == 'text':
parse_clipboard(args)
else:
take_screenshot()
elif args.files is not None:
if config.uploader in ['ftp', 'sftp']:
if mode != 'screenshot' and '.' in file:
ext = '.' + file.rsplit('.', 1)[1]
# TODO: mode file for FTP
fullpath, filename = ftp_upload(mode, ext)
elif config.uploader == 'curl':
if mode=='screenshot':
filename = generate_filename(length=config.length, ext='.png')
fullpath = os.path.join(config.local_directory, filename)
take_screenshot(fullpath)
else:
fullpath = file
curl_upload(fullpath)
else:
print('Unknown mode')
sys.exit(-1)
url = config.url_template.format(filename)
notify_user(url)
"""