Compare commits
	
		
			6 Commits
		
	
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 1c78b0b374 | |
|  | 96b2bb7ae1 | |
|  | 39ae5f83d1 | |
|  | c94a7276be | |
|  | 3d9f3d6cf3 | |
|  | 7123d78adc | 
							
								
								
									
										20
									
								
								README.md
								
								
								
								
							
							
						
						
									
										20
									
								
								README.md
								
								
								
								
							|  | @ -1,10 +1,14 @@ | ||||||
| # Grail | # Grail | ||||||
| 
 | 
 | ||||||
| * Author: Lukas Mahler | 
 | ||||||
| * Copyright: (C)2018-2021 | Version: 0.6.1   | ||||||
| * Version: 0.5.1 | Date: 23.05.2021 | ||||||
| * Date: 16.01.2021 | 
 | ||||||
| ********************************* | ## Description: | ||||||
|  Instant Upload Screenshot-Tool based on the idea of Gyazoo. |  Instant Upload Screenshot-Tool based on the idea of Gyazoo.   | ||||||
|  **->** **MS Windows only!** |  [Edit the settings.ini file for online upload (using either SFTP or Nextcloud)] | ||||||
| ********************************* | 
 | ||||||
|  |  ->Currently Windows only! | ||||||
|  | 
 | ||||||
|  | ## Precompiled: | ||||||
|  | [Download](https://git.lukasmahler.de/attachments/607f8474-4c42-4c89-a245-3cbd4b66be58 "0.6.1") | ||||||
							
								
								
									
										177
									
								
								grail.py
								
								
								
								
							
							
						
						
									
										177
									
								
								grail.py
								
								
								
								
							|  | @ -1,7 +1,7 @@ | ||||||
| __author__ = "Lukas Mahler" | __author__ = "Lukas Mahler" | ||||||
| __copyright__ = "Copyright 2018-2021" | __copyright__ = "Copyright 2018-2021" | ||||||
| __version__ = "0.5.1" | __version__ = "0.6.1" | ||||||
| __date__ = "16.01.2021" | __date__ = "23.05.2021" | ||||||
| __email__ = "lm@ankerlab.de" | __email__ = "lm@ankerlab.de" | ||||||
| __status__ = "Development" | __status__ = "Development" | ||||||
| 
 | 
 | ||||||
|  | @ -12,6 +12,7 @@ try: | ||||||
|     import sys |     import sys | ||||||
|     import webbrowser |     import webbrowser | ||||||
|     from io import BytesIO |     from io import BytesIO | ||||||
|  |     from requests import head | ||||||
|     from shutil import rmtree |     from shutil import rmtree | ||||||
|     from getpass import getpass |     from getpass import getpass | ||||||
|     from tempfile import gettempdir |     from tempfile import gettempdir | ||||||
|  | @ -25,6 +26,7 @@ try: | ||||||
|     from fillscreen import Ui_View |     from fillscreen import Ui_View | ||||||
| 
 | 
 | ||||||
|     # Customs |     # Customs | ||||||
|  |     import owncloud | ||||||
|     import win32gui |     import win32gui | ||||||
|     import win32clipboard |     import win32clipboard | ||||||
|     import paramiko |     import paramiko | ||||||
|  | @ -49,7 +51,7 @@ class Fillscreen(QtWidgets.QWidget, Ui_View): | ||||||
|         ############################################################################################### |         ############################################################################################### | ||||||
|         ############################################################################################### |         ############################################################################################### | ||||||
| 
 | 
 | ||||||
|         # Bastelstüble wegen Transparentem Window welches aber den Input auf unterliegendes blockieren soll |         # Monkeycode for trying to block input for content under the transparent window. | ||||||
| 
 | 
 | ||||||
|         # self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True) |         # self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True) | ||||||
|         # self.setBackgroundRole(QtGui.QPalette.Base) |         # self.setBackgroundRole(QtGui.QPalette.Base) | ||||||
|  | @ -121,42 +123,69 @@ 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): | def read_ini(rootdir): | ||||||
|     myini = {} |     myini = {} | ||||||
|     config = ConfigParser() |     config = ConfigParser(inline_comment_prefixes=";") | ||||||
|     try: |     try: | ||||||
|         config.read_file(open(rootdir+'settings.ini')) |         config.read_file(open(rootdir + 'settings.ini')) | ||||||
|     except Exception as e: |     except FileNotFoundError: | ||||||
|         print("ERROR: Couldn't locate a 'settings.ini' |||", e) |         print("ERROR: Couldn't locate a 'settings.ini'") | ||||||
|  |         print("--> Trying to create new blank one.") | ||||||
|         # Creating new blank ini |         # Creating new blank ini | ||||||
|         with open(rootdir+'settings.ini', 'w') as f: |         with open(rootdir + 'settings.ini', 'w') as f: | ||||||
|             txt = "[MAIN]\n" \ |             txt = ( | ||||||
|                   "# MODE EITHER ONLINE OR OFFLINE\nMODE = OFFLINE\n\n\n" \ |                 "# MAIN SETTINGS\n" | ||||||
|                   "# IF MODE IS ONLINE PROVIDE THE SFTP INFO BELOW\n" \ |                 "[MAIN]\n" | ||||||
|                   "[ONLINE]\n\n" \ |                 "MODE = LOCAL                ; MODE EITHER SFTP, NEXTCLOUD OR LOCAL\n" | ||||||
|                   "# URL EITHER IS AN IP OR A FQDN\nURL = \n\n" \ |                 "TIMEOUT = 5                 ; TIMEOUT WHEN TESTING SFTP CONNECTION\n"  | ||||||
|                   "# PORT IS THE SSH PORT\nPORT = 22\n\n" \ |                 "SSL = TRUE                  ; USING HTTP (FALSE) OR HTTPS (TRUE) URLS\n" | ||||||
|                   "# THE TIME IN SECONDS TO TRY TO CONNECT\nTIMEOUT = 5\n\n" \ |                 "\n" | ||||||
|                   "# YOUR SSH USER, THIS CAN BE BLANK TO GET ASKED INTERACTIVELY\nUSR = \nPASS = \n\n" \ |                 "# PROVIDE SFTP INFO BELOW\n" | ||||||
|                   "# THE LOCAL SERVER PATH WHERE TO PUT THE SCREENSHOT\nPTH = ./Screens/\n\n" \ |                 "[SFTP]\n" | ||||||
|                   "# THIS SHOULD BE THE FULL ONLINE URL\nWHERE = \n\n\n" \ |                 "URL =                       ; URL EITHER IS AN IP OR A FQDN\n" | ||||||
|                   "# IF MODE IS OFFLINE YOU MAY CHANGE THE SETTINGS BELOW\n" \ |                 "PORT =                      ; PORT IS THE SSH PORT\n" | ||||||
|                   "[OFFLINE]\n\n" \ |                 "USR =                       ; YOUR SSH USER, THIS CAN BE BLANK TO GET ASKED INTERACTIVELY\n" | ||||||
|                   "WHERE = " |                 "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" | ||||||
|  |                 "\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) |             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') |     mode = config.get('MAIN', 'MODE') | ||||||
|     if mode == "ONLINE": |     if mode == "SFTP": | ||||||
|         url = config.get('ONLINE', 'URL') |         url = config.get(mode, 'URL') | ||||||
|         port = int(config.get('ONLINE', 'PORT')) |         port = int(config.get(mode, 'PORT')) | ||||||
|         timeout = int(config.get('ONLINE', 'TIMEOUT')) |         usr = config.get(mode, 'USR') | ||||||
|         usr = config.get('ONLINE', 'USR') |         passw = config.get(mode, 'PASS') | ||||||
|         passw = config.get('ONLINE', 'PASS') |         pth = config.get(mode, 'PTH') | ||||||
|         pth = config.get('ONLINE', 'PTH') |         where = config.get(mode, 'WHERE') | ||||||
|         where = config.get('ONLINE', 'WHERE') |  | ||||||
|         myini.update( |         myini.update( | ||||||
|             MODE    = mode, |             MODE    = mode, | ||||||
|             URL     = url, |             URL     = url, | ||||||
|  | @ -165,10 +194,22 @@ def read_ini(rootdir): | ||||||
|             USR     = usr, |             USR     = usr, | ||||||
|             PASS    = passw, |             PASS    = passw, | ||||||
|             PTH     = pth, |             PTH     = pth, | ||||||
|             WHERE   = where |             WHERE   = sslurl(where, ssl) | ||||||
|         ) |         ) | ||||||
|     elif mode == "OFFLINE": |     elif mode == "NEXTCLOUD": | ||||||
|         where = config.get('OFFLINE', 'WHERE') |         url = sslurl(config.get(mode, 'URL'), ssl) | ||||||
|  |         usr = config.get(mode, 'USR') | ||||||
|  |         passw = config.get(mode, 'PASS') | ||||||
|  |         pth = config.get(mode, 'PTH') | ||||||
|  |         myini.update( | ||||||
|  |             MODE    = mode, | ||||||
|  |             URL     = url, | ||||||
|  |             USR     = usr, | ||||||
|  |             PASS    = passw, | ||||||
|  |             PTH     = pth, | ||||||
|  |         ) | ||||||
|  |     elif mode == "LOCAL": | ||||||
|  |         where = config.get('LOCAL', 'WHERE') | ||||||
|         myini.update( |         myini.update( | ||||||
|             MODE	= mode, |             MODE	= mode, | ||||||
|             WHERE	= where |             WHERE	= where | ||||||
|  | @ -228,17 +269,19 @@ def do_screen(start, end): | ||||||
| 
 | 
 | ||||||
|     im = getRectAsImage(frame) |     im = getRectAsImage(frame) | ||||||
|     send_to_clipboard(im) |     send_to_clipboard(im) | ||||||
|     timestamp = strftime("%Y-%m-%d_%H.%M.%S") |     timestamp = strftime("%Y-%m-%d_%H-%M-%S") | ||||||
| 
 | 
 | ||||||
|     tempdir = gettempdir()+"\\Screens" |     tempdir = gettempdir()+"\\Screens" | ||||||
|     # print("DEBUG:",tempdir) |     # print("DEBUG:",tempdir) | ||||||
|     if not os.path.exists(tempdir): |     if not os.path.exists(tempdir): | ||||||
|         os.makedirs(tempdir) |         os.makedirs(tempdir) | ||||||
|     tempsave = '{0}\\{1}.png'.format(tempdir, 'Screen_'+timestamp) |     tempsave = '{0}\\{1}.png'.format(tempdir, timestamp) | ||||||
|     im.save(tempsave) |     im.save(tempsave) | ||||||
| 
 | 
 | ||||||
|     if settings['MODE'] == "ONLINE": |     if settings['MODE'] == "SFTP": | ||||||
|         upload_to_url(tempsave) |         upload_to_url_sftp(tempsave) | ||||||
|  |     elif settings['MODE'] == "NEXTCLOUD": | ||||||
|  |         upload_to_url_nextcloud(tempsave) | ||||||
|     else: |     else: | ||||||
|         save_to_local(tempsave) |         save_to_local(tempsave) | ||||||
| 
 | 
 | ||||||
|  | @ -263,7 +306,7 @@ def send_to_clipboard(im=None): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # https://stackoverflow.com/questions/432385/sftp-in-python-platform-independent | # https://stackoverflow.com/questions/432385/sftp-in-python-platform-independent | ||||||
| def upload_to_url(tempsave): | def upload_to_url_sftp(tempsave): | ||||||
| 
 | 
 | ||||||
|     # SFTP INFO |     # SFTP INFO | ||||||
|     url 	= settings['URL'] |     url 	= settings['URL'] | ||||||
|  | @ -280,13 +323,13 @@ def upload_to_url(tempsave): | ||||||
|         s.close() |         s.close() | ||||||
|     except Exception as e: |     except Exception as e: | ||||||
|         print("ERROR: Connection failed. |||", 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) |         save_to_local(tempsave, fallback=1) | ||||||
|         return |         return | ||||||
| 
 | 
 | ||||||
|     # If not provided ask for Username & Password |     # If not provided ask for Username & Password | ||||||
|     if not usr: |     if not usr: | ||||||
|         usr = input("Please provide your Username: ") |         usr = input("Please provide a username: ") | ||||||
| 
 | 
 | ||||||
|     if not passw: |     if not passw: | ||||||
|         passw = getpass("Please provide the password for {0}: ".format(usr)) |         passw = getpass("Please provide the password for {0}: ".format(usr)) | ||||||
|  | @ -296,7 +339,7 @@ def upload_to_url(tempsave): | ||||||
|         transport.connect(username=usr, password=passw) |         transport.connect(username=usr, password=passw) | ||||||
|     except Exception as e: |     except Exception as e: | ||||||
|         print("ERROR: SSH2 negotiation or authentication failed. |||", 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) |         save_to_local(tempsave, fallback=1) | ||||||
|         return |         return | ||||||
| 
 | 
 | ||||||
|  | @ -310,6 +353,51 @@ def upload_to_url(tempsave): | ||||||
|     open_url(where) |     open_url(where) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | def upload_to_url_nextcloud(tempsave): | ||||||
|  | 
 | ||||||
|  |     # NEXTCLOUD INFO | ||||||
|  |     url 	= settings['URL'] | ||||||
|  |     usr 	= settings['USR'] | ||||||
|  |     passw 	= settings['PASS'] | ||||||
|  |     pth		= settings['PTH'] + 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 | ||||||
|  | 
 | ||||||
|  |     # Had to monkeypatch the pyocclient libary here to stop AttributeErrors on 'share_file_with_link' calls | ||||||
|  |     # (https://github.com/owncloud/pyocclient/issues/263) | ||||||
|  | 
 | ||||||
|  |     print("Starting to Upload...") | ||||||
|  |     nxt.put_file(pth, tempsave) | ||||||
|  |     link_info = nxt.share_file_with_link(pth) | ||||||
|  |     where = link_info.get_link() | ||||||
|  | 
 | ||||||
|  |     print("Screen was Uploaded: URL: " + where) | ||||||
|  |     open_url(where) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def save_to_local(tempsave, fallback=None): | def save_to_local(tempsave, fallback=None): | ||||||
| 
 | 
 | ||||||
|     if not fallback: |     if not fallback: | ||||||
|  | @ -317,14 +405,14 @@ def save_to_local(tempsave, fallback=None): | ||||||
|     else: |     else: | ||||||
|         print("    -> Did fallback!") |         print("    -> Did fallback!") | ||||||
|         config = ConfigParser() |         config = ConfigParser() | ||||||
|         config.read_file(open(root+'_settings.ini')) |         config.read_file(open(root+'settings.ini')) | ||||||
|         where = config.get('OFFLINE', 'WHERE') |         where = config.get('LOCAL', 'WHERE') | ||||||
| 
 | 
 | ||||||
|     if not where: |     if not where: | ||||||
|         print("No local Screens folder provided, creating one...") |         print("No local Screens folder provided, creating one...") | ||||||
|         where = os.path.dirname(os.path.abspath(__file__))+"\\Screens" |         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): |     if not os.path.exists(where): | ||||||
|         os.makedirs(where) |         os.makedirs(where) | ||||||
|  | @ -333,6 +421,7 @@ def save_to_local(tempsave, fallback=None): | ||||||
|     dst = where + "\\" + os.path.basename(tempsave) |     dst = where + "\\" + os.path.basename(tempsave) | ||||||
|     # print("Source:",src,"\nDestination:",dst) |     # print("Source:",src,"\nDestination:",dst) | ||||||
|     os.rename(src, dst) |     os.rename(src, dst) | ||||||
|  |     os.startfile(dst) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def open_url(where): | def open_url(where): | ||||||
|  |  | ||||||
|  | @ -1,11 +0,0 @@ | ||||||
| [ship] |  | ||||||
| param = --onefile --windowed |  | ||||||
| icon = C:\Users\lukas\Desktop\Dump\08_Resources\camera.ico |  | ||||||
| 
 |  | ||||||
| [debug] |  | ||||||
| param = --onefile |  | ||||||
| icon = C:\Users\lukas\Desktop\Dump\08_Resources\camera.ico |  | ||||||
| 
 |  | ||||||
| [test] |  | ||||||
| param = --onedir --noupx --add-binary msvcp140.dll;. |  | ||||||
| icon = C:\Users\lukas\Desktop\Dump\08_Resources\camera.ico |  | ||||||
		Loading…
	
		Reference in New Issue