From c94a7276be6632974a0717b07fe6edc9e72e6241 Mon Sep 17 00:00:00 2001 From: Lukas Date: Sat, 22 May 2021 21:20:11 +0200 Subject: [PATCH] 1. Add Nextcloud as upload option 2. Rewrite ini file with inline comments 3. Fix local Upload v. 0.6 --- README.md | 5 +- grail.py | 176 +++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 137 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 6f80187..915ec08 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,13 @@ -# Grail +# Grail(cloud) * Version: 0.5.1 * Date: 16.01.2021 ********************************* Instant Upload Screenshot-Tool based on the idea of Gyazoo. + + [This needs a settings.ini containing credentials] + **->MS Windows only!** ********************************* [Precompiled Download](https://git.lukasmahler.de/attachments/92de34c2-faf6-473d-87a0-0e885809540b "download") \ No newline at end of file diff --git a/grail.py b/grail.py index 1602031..5cf8728 100644 --- a/grail.py +++ b/grail.py @@ -1,7 +1,7 @@ __author__ = "Lukas Mahler" __copyright__ = "Copyright 2018-2021" -__version__ = "0.5.1" -__date__ = "16.01.2021" +__version__ = "0.6.0" +__date__ = "22.05.2021" __email__ = "lm@ankerlab.de" __status__ = "Development" @@ -12,6 +12,7 @@ try: import sys import webbrowser from io import BytesIO + from requests import head from shutil import rmtree from getpass import getpass from tempfile import gettempdir @@ -25,6 +26,7 @@ try: from fillscreen import Ui_View # Customs + import owncloud import win32gui import win32clipboard import paramiko @@ -121,42 +123,70 @@ class Fillscreen(QtWidgets.QWidget, Ui_View): ################################################################################################### -################################################################################################### +################################################################################################### + +def sslurl(url, ssl): + if ssl: + url = "https://" + url + else: + url = "http://" + url + + return url def read_ini(rootdir): myini = {} - config = ConfigParser() + config = ConfigParser(inline_comment_prefixes=";") try: - config.read_file(open(rootdir+'settings.ini')) - except Exception as e: - print("ERROR: Couldn't locate a 'settings.ini' |||", e) + config.read_file(open(rootdir + 'settings.ini')) + except FileNotFoundError: + print("ERROR: Couldn't locate a 'settings.ini'") + print("--> Trying to create new blank one.") # Creating new blank ini - with open(rootdir+'settings.ini', 'w') as f: - txt = "[MAIN]\n" \ - "# MODE EITHER ONLINE OR OFFLINE\nMODE = OFFLINE\n\n\n" \ - "# IF MODE IS ONLINE PROVIDE THE SFTP INFO BELOW\n" \ - "[ONLINE]\n\n" \ - "# URL EITHER IS AN IP OR A FQDN\nURL = \n\n" \ - "# PORT IS THE SSH PORT\nPORT = 22\n\n" \ - "# THE TIME IN SECONDS TO TRY TO CONNECT\nTIMEOUT = 5\n\n" \ - "# YOUR SSH USER, THIS CAN BE BLANK TO GET ASKED INTERACTIVELY\nUSR = \nPASS = \n\n" \ - "# THE LOCAL SERVER PATH WHERE TO PUT THE SCREENSHOT\nPTH = ./Screens/\n\n" \ - "# THIS SHOULD BE THE FULL ONLINE URL\nWHERE = \n\n\n" \ - "# IF MODE IS OFFLINE YOU MAY CHANGE THE SETTINGS BELOW\n" \ - "[OFFLINE]\n\n" \ - "WHERE = " + with open(rootdir + 'settings.ini', 'w') as f: + txt = ( + "# MAIN SETTINGS\n" + "[MAIN]\n" + "MODE = LOCAL ; MODE EITHER SFTP, NEXTCLOUD OR LOCAL\n" + "TIMEOUT = 5 ; TIMEOUT WHEN TESTING SFTP CONNECTION\n" + "SSL = TRUE ; USING HTTP (FALSE) OR HTTPS (TRUE) URLS\n" + "\n" + "# PROVIDE SFTP INFO BELOW\n" + "[SFTP]\n" + "URL = ; URL EITHER IS AN IP OR A FQDN\n" + "PORT = ; PORT IS THE SSH PORT\n" + "USR = ; YOUR SSH USER, THIS CAN BE BLANK TO GET ASKED INTERACTIVELY\n" + "PASS = ; YOUR SSH USERS PW, THIS CAN BE BLANK TO GET ASKED INTERACTIVELY\n" + "PTH = ; THE LOCAL SERVER PATH WHERE TO PUT THE SCREENSHOT\n" + "WHERE = ; THIS SHOULD BE THE FULL ONLINE URL\n" + "\n" + "# PROVIDE NEXTCLOUD INFO BELOW\n" + "[NEXTCLOUD]\n" + "URL = ; URL EITHER IS AN IP OR A FQDN OF A NEXTCLOUD SERVER\n" + "USR = ; YOUR NEXTCLOUD USER, THIS CAN BE BLANK TO GET ASKED INTERACTIVELY\n" + "PASS = ; YOUR NEXTCLOUD USERS PW, THIS CAN BE BLANK TO GET ASKED INTERACTIVELY\n" + "PTH = ; THE NEXTCLOUD FOLDER PATH WHERE TO PUT THE SCREENSHOT\n" + "WHERE = ; THIS SHOULD BE THE FULL ONLINE URL\n" + "\n" + "# IF MODE IS LOCAL YOU MAY CHANGE THE SETTINGS BELOW\n" + "[LOCAL]\n" + "WHERE = ; THIS SHOULD BE A FULL LOCAL PATH\n" + ) f.write(txt) + config.read_file(open(rootdir + 'settings.ini')) + + # General Settings + timeout = int(config.get('MAIN', 'TIMEOUT')) + ssl = config.get('MAIN', 'SSL') mode = config.get('MAIN', 'MODE') - if mode == "ONLINE": - url = config.get('ONLINE', 'URL') - port = int(config.get('ONLINE', 'PORT')) - timeout = int(config.get('ONLINE', 'TIMEOUT')) - usr = config.get('ONLINE', 'USR') - passw = config.get('ONLINE', 'PASS') - pth = config.get('ONLINE', 'PTH') - where = config.get('ONLINE', 'WHERE') + if mode == "SFTP": + url = config.get(mode, 'URL') + port = int(config.get(mode, 'PORT')) + usr = config.get(mode, 'USR') + passw = config.get(mode, 'PASS') + pth = config.get(mode, 'PTH') + where = config.get(mode, 'WHERE') myini.update( MODE = mode, URL = url, @@ -165,10 +195,25 @@ def read_ini(rootdir): USR = usr, PASS = passw, PTH = pth, - WHERE = where + WHERE = sslurl(where, ssl) ) - elif mode == "OFFLINE": - where = config.get('OFFLINE', 'WHERE') + elif mode == "NEXTCLOUD": + url = sslurl(config.get(mode, 'URL'), ssl) + usr = config.get(mode, 'USR') + passw = config.get(mode, 'PASS') + pth = config.get(mode, 'PTH') + where = config.get(mode, 'WHERE') + myini.update( + MODE = mode, + URL = url, + TIMEOUT = timeout, + USR = usr, + PASS = passw, + PTH = pth, + WHERE = sslurl(where, ssl) + ) + elif mode == "LOCAL": + where = config.get('LOCAL', 'WHERE') myini.update( MODE = mode, WHERE = where @@ -228,17 +273,19 @@ def do_screen(start, end): im = getRectAsImage(frame) send_to_clipboard(im) - timestamp = strftime("%Y-%m-%d_%H.%M.%S") + timestamp = strftime("%Y-%m-%d_%H-%M-%S") tempdir = gettempdir()+"\\Screens" # print("DEBUG:",tempdir) if not os.path.exists(tempdir): os.makedirs(tempdir) - tempsave = '{0}\\{1}.png'.format(tempdir, 'Screen_'+timestamp) + tempsave = '{0}\\{1}.png'.format(tempdir, timestamp) im.save(tempsave) - if settings['MODE'] == "ONLINE": - upload_to_url(tempsave) + if settings['MODE'] == "SFTP": + upload_to_url_sftp(tempsave) + elif settings['MODE'] == "NEXTCLOUD": + upload_to_url_nextcloud(tempsave) else: save_to_local(tempsave) @@ -263,7 +310,7 @@ def send_to_clipboard(im=None): # https://stackoverflow.com/questions/432385/sftp-in-python-platform-independent -def upload_to_url(tempsave): +def upload_to_url_sftp(tempsave): # SFTP INFO url = settings['URL'] @@ -280,13 +327,13 @@ def upload_to_url(tempsave): s.close() except Exception as e: print("ERROR: Connection failed. |||", e) - print("\nFalling back to local save...") + print("\n --> Falling back to local mode") save_to_local(tempsave, fallback=1) return # If not provided ask for Username & Password if not usr: - usr = input("Please provide your Username: ") + usr = input("Please provide a username: ") if not passw: passw = getpass("Please provide the password for {0}: ".format(usr)) @@ -296,7 +343,7 @@ def upload_to_url(tempsave): transport.connect(username=usr, password=passw) except Exception as e: print("ERROR: SSH2 negotiation or authentication failed. |||", e) - print("\nFalling back to local save...") + print("\n--> Falling back to local mode") save_to_local(tempsave, fallback=1) return @@ -310,6 +357,48 @@ def upload_to_url(tempsave): open_url(where) +def upload_to_url_nextcloud(tempsave): + + # NEXTCLOUD INFO + url = settings['URL'] + timeout = settings['TIMEOUT'] + usr = settings['USR'] + passw = settings['PASS'] + pth = settings['PTH'] + os.path.basename(tempsave) + where = settings['WHERE'] + os.path.basename(tempsave) + + # Test Connection first or go into fallback + r = head(url) + httpc = str(r.status_code)[0] + if httpc == "4" or httpc == "5": + print("ERROR: HTTP Statuscode for URL [{0}] is [{1}]".format(url, r.status_code)) + print("\n--> Falling back to local mode") + save_to_local(tempsave, fallback=1) + return + + # If not provided ask for Username & Password + if not usr: + usr = input("Please provide a username: ") + + if not passw: + passw = getpass("Please provide the password for {0}: ".format(usr)) + + try: + nxt = owncloud.Client(url) + nxt.login(usr, passw) + except Exception as e: + print("ERROR: ", e) + print("\n--> Falling back to local mode") + save_to_local(tempsave, fallback=1) + return + + print("Starting to Upload...") + nxt.put_file(pth, tempsave) + + print("Screen was Uploaded: URL: " + where) + open_url(where) + + def save_to_local(tempsave, fallback=None): if not fallback: @@ -317,14 +406,14 @@ def save_to_local(tempsave, fallback=None): else: print(" -> Did fallback!") config = ConfigParser() - config.read_file(open(root+'_settings.ini')) - where = config.get('OFFLINE', 'WHERE') + config.read_file(open(root+'settings.ini')) + where = config.get('LOCAL', 'WHERE') if not where: print("No local Screens folder provided, creating one...") where = os.path.dirname(os.path.abspath(__file__))+"\\Screens" - print("OFFLINE MODE: Screenshot Folder:", where) + print("LOCAL MODE: Screenshot Folder:", where) if not os.path.exists(where): os.makedirs(where) @@ -333,6 +422,7 @@ def save_to_local(tempsave, fallback=None): dst = where + "\\" + os.path.basename(tempsave) # print("Source:",src,"\nDestination:",dst) os.rename(src, dst) + os.startfile(dst) def open_url(where):