Merge pull request #2896 from PySimpleGUI/Dev-latest
The new readme creator and proposed new call reference file
This commit is contained in:
		
						commit
						c7bcf22911
					
				
					 8 changed files with 2410 additions and 2112 deletions
				
			
		|  | @ -27,20 +27,14 @@ HOW DO I INSERT IMAGES ??? | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
| 
 | 
 | ||||||
| [](http://pepy.tech/project/pysimplegui) tkinter | [](http://pepy.tech/project/pysimplegui) tkinter | ||||||
| 
 | [](https://pepy.tech/project/pysimplegui27) tk 2.7 | ||||||
| [](https://pepy.tech/project/pysimplegui27) tkinter 2.7 |  | ||||||
| 
 |  | ||||||
| [](https://pepy.tech/project/pysimpleguiqt) Qt | [](https://pepy.tech/project/pysimpleguiqt) Qt | ||||||
| 
 |  | ||||||
| [](https://pepy.tech/project/pysimpleguiWx) WxPython | [](https://pepy.tech/project/pysimpleguiWx) WxPython | ||||||
| 
 |  | ||||||
| [](https://pepy.tech/project/pysimpleguiWeb) Web (Remi) | [](https://pepy.tech/project/pysimpleguiWeb) Web (Remi) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 
 | 
 | ||||||
| [](https://pypi.org/project/pysimplegui/) tkinter | [](https://pypi.org/project/pysimplegui/) tkinter | ||||||
| [](https://pypi.org/project/pysimpleguiqt/) Qt | [](https://pypi.org/project/pysimpleguiqt/) Qt | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1999
									
								
								readme_creator/5_call_reference.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1999
									
								
								readme_creator/5_call_reference.md
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										42
									
								
								readme_creator/LoG.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								readme_creator/LoG.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | ||||||
|  | [ | ||||||
|  |   { | ||||||
|  |     "message_type": "info", | ||||||
|  |     "message_text": "STARTING", | ||||||
|  |     "message_time": 2 | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "message_type": "warning", | ||||||
|  |     "message_text": "ALERT ------  Hi, Mike! Please, fix ':return:' in 'PopupNonBlocking'        \tIF you want to see 'return' row in 'signature table'", | ||||||
|  |     "message_time": 3 | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "message_type": "warning", | ||||||
|  |     "message_text": "ALERT ------  Hi, Mike! Please, fix ':return:' in 'PopupAnimated'           \tIF you want to see 'return' row in 'signature table'", | ||||||
|  |     "message_time": 4 | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "message_type": "info", | ||||||
|  |     "message_text": "\n=================================================\nSTARTING TO INSERT markdown text into 2_readme.md\n=================================================\n", | ||||||
|  |     "message_time": 5 | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "message_type": "info", | ||||||
|  |     "message_text": "DONE 8 TAGS:\n<!-- <+func.Popup+> --> - COMPLETE\n<!-- <+func.popup_scrolled+> --> - COMPLETE\n<!-- <+func.popup_no_wait+> --> - COMPLETE\n<!-- <+func.popup_get_text+> --> - COMPLETE\n<!-- <+func.popup_get_file+> --> - COMPLETE\n<!-- <+func.popup_get_folder+> --> - COMPLETE\n<!-- <+func.popup_animated+> --> - COMPLETE\n<!-- <+func.one_line_progress_meter+> --> - COMPLETE", | ||||||
|  |     "message_time": 6 | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "message_type": "info", | ||||||
|  |     "message_text": "No bad tags, YES!", | ||||||
|  |     "message_time": 7 | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "message_type": "info", | ||||||
|  |     "message_text": "Deleting html comments", | ||||||
|  |     "message_time": 8 | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "message_type": "info", | ||||||
|  |     "message_text": "ending. writing to a file///////////////", | ||||||
|  |     "message_time": 9 | ||||||
|  |   } | ||||||
|  | ] | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| #!/usr/bin/python3 | #!/usr/bin/python3 | ||||||
| 
 | 
 | ||||||
| version = __version__ = "4.19.0 Released 5-May-2020" | version = __version__ = "4.19.0.3 Unreleased - Window.set_title added, removed resetting stdout when flush happens, fixed MenuBar tearoff not working" | ||||||
| 
 | 
 | ||||||
| port = 'PySimpleGUI' | port = 'PySimpleGUI' | ||||||
| 
 | 
 | ||||||
|  | @ -307,7 +307,6 @@ DEFAULT_SCROLLBAR_COLOR = None | ||||||
| # A transparent button is simply one that matches the background | # A transparent button is simply one that matches the background | ||||||
| # TRANSPARENT_BUTTON = 'This constant has been depricated. You must set your button background = background it is on for it to be transparent appearing' | # TRANSPARENT_BUTTON = 'This constant has been depricated. You must set your button background = background it is on for it to be transparent appearing' | ||||||
| 
 | 
 | ||||||
| TRANSPARENT_BUTTON = ('#F0F0F0', '#F0F0F0')  # Use (sg.theme_background_color(), sg.theme_background_color()) instead!!! |  | ||||||
| 
 | 
 | ||||||
| # -------------------------------------------------------------------------------- | # -------------------------------------------------------------------------------- | ||||||
| # Progress Bar Relief Choices | # Progress Bar Relief Choices | ||||||
|  | @ -358,7 +357,7 @@ LISTBOX_SELECT_MODE_SINGLE = 'single' | ||||||
| TABLE_SELECT_MODE_NONE = tk.NONE | TABLE_SELECT_MODE_NONE = tk.NONE | ||||||
| TABLE_SELECT_MODE_BROWSE = tk.BROWSE | TABLE_SELECT_MODE_BROWSE = tk.BROWSE | ||||||
| TABLE_SELECT_MODE_EXTENDED = tk.EXTENDED | TABLE_SELECT_MODE_EXTENDED = tk.EXTENDED | ||||||
| DEFAULT_TABLE_SECECT_MODE = TABLE_SELECT_MODE_EXTENDED | DEFAULT_TABLE_SELECT_MODE = TABLE_SELECT_MODE_EXTENDED | ||||||
| 
 | 
 | ||||||
| TITLE_LOCATION_TOP = tk.N | TITLE_LOCATION_TOP = tk.N | ||||||
| TITLE_LOCATION_BOTTOM = tk.S | TITLE_LOCATION_BOTTOM = tk.S | ||||||
|  | @ -642,7 +641,7 @@ class Element(): | ||||||
|         self.Visible = visible |         self.Visible = visible | ||||||
|         self.TKRightClickMenu = None |         self.TKRightClickMenu = None | ||||||
|         self.Widget = None  # Set when creating window. Has the main tkinter widget for element |         self.Widget = None  # Set when creating window. Has the main tkinter widget for element | ||||||
|         self.Tearoff = False |         # self.Tearoff = False          # why was this here?? should already be in the Menubar element...confusing... | ||||||
|         self.ParentRowFrame = None  # type tk.Frame |         self.ParentRowFrame = None  # type tk.Frame | ||||||
|         self.metadata = metadata  # type: Any |         self.metadata = metadata  # type: Any | ||||||
|         self.user_bind_dict = {}  # Used when user defines a tkinter binding using bind method - convert bind string to key modifier |         self.user_bind_dict = {}  # Used when user defines a tkinter binding using bind method - convert bind string to key modifier | ||||||
|  | @ -2592,10 +2591,11 @@ class TKOutput(tk.Frame): | ||||||
| 
 | 
 | ||||||
|     def flush(self): |     def flush(self): | ||||||
|         """ |         """ | ||||||
|         This doesn't look right.  This restores stdout and stderr to their old values |         Flush parameter was passed into a print statement. | ||||||
|  |         For now doing nothing.  Not sure what action should be taken to ensure a flush happens regardless. | ||||||
|         """ |         """ | ||||||
|         sys.stdout = self.previous_stdout |         return | ||||||
|         sys.stderr = self.previous_stderr | 
 | ||||||
| 
 | 
 | ||||||
|     def __del__(self): |     def __del__(self): | ||||||
|         """ |         """ | ||||||
|  | @ -7810,6 +7810,17 @@ class Window: | ||||||
|         """ |         """ | ||||||
|         return |         return | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |     def set_title(self, title): | ||||||
|  |         """ | ||||||
|  |         Change the title of the window | ||||||
|  | 
 | ||||||
|  |         :param title: The string to set the title to | ||||||
|  |         :type title: str | ||||||
|  |         """ | ||||||
|  | 
 | ||||||
|  |         self.TKroot.wm_title(str(title)) | ||||||
|  | 
 | ||||||
|     # def __enter__(self): |     # def __enter__(self): | ||||||
|     #     """ |     #     """ | ||||||
|     #     WAS used with context managers which are no longer needed nor advised.  It is here for legacy support and |     #     WAS used with context managers which are no longer needed nor advised.  It is here for legacy support and | ||||||
|  | @ -13055,6 +13066,9 @@ def theme_background_color(color=None): | ||||||
|         set_options(background_color=color) |         set_options(background_color=color) | ||||||
|     return DEFAULT_BACKGROUND_COLOR |     return DEFAULT_BACKGROUND_COLOR | ||||||
| 
 | 
 | ||||||
|  | # This "constant" is misleading but rather than remove and break programs, will try this method instead | ||||||
|  | TRANSPARENT_BUTTON = (theme_background_color(), theme_background_color())  # replaces an older version that had hardcoded numbers | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| def theme_element_background_color(color=None): | def theme_element_background_color(color=None): | ||||||
|     """ |     """ | ||||||
|  |  | ||||||
|  | @ -1,6 +1,8 @@ | ||||||
| from inspect import getmembers, isfunction, isclass, getsource, signature, _empty, isdatadescriptor | from inspect import getmembers, isfunction, isclass, getsource, signature, _empty, isdatadescriptor | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
| import PySimpleGUIlib, click, textwrap, logging, json, re, os | import PySimpleGUIlib, click, textwrap, logging, json, re, os | ||||||
|  | import os | ||||||
|  | cd = CD = os.path.dirname(os.path.abspath(__file__)) | ||||||
| 
 | 
 | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| triplet = namedtuple('triplet', 'name value atype'.split(' ')) | triplet = namedtuple('triplet', 'name value atype'.split(' ')) | ||||||
|  | @ -88,6 +90,8 @@ def get_return_part(code: str, line_break=None) -> str: | ||||||
|         return '' |         return '' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |      | ||||||
|  |          | ||||||
|     only_return = code[code.index(':return:')+len(':return:'):].strip().replace('\n', line_break) |     only_return = code[code.index(':return:')+len(':return:'):].strip().replace('\n', line_break) | ||||||
|     if ':rtype' in only_return: |     if ':rtype' in only_return: | ||||||
|         only_return = only_return.split(':rtype')[0] |         only_return = only_return.split(':rtype')[0] | ||||||
|  | @ -198,6 +202,8 @@ def special_cases(function_name, function_obj, sig, doc_string, line_break=None) | ||||||
| 
 | 
 | ||||||
| def get_doc_desc(doc, original_obj): | def get_doc_desc(doc, original_obj): | ||||||
| 
 | 
 | ||||||
|  |      | ||||||
|  |      | ||||||
|     return_in = ':return' in doc |     return_in = ':return' in doc | ||||||
|     param_in = ':param' in doc |     param_in = ':param' in doc | ||||||
|      |      | ||||||
|  | @ -254,8 +260,11 @@ def get_sig_table_parts(function_obj, function_name, doc_string, | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     sig_content = f',\n{TAB_char}'.join(rows) if len(rows) > 2 else f', '.join(rows) if rows else '' |     sig_content = f',\n{TAB_char}'.join(rows) if len(rows) > 2 else f', '.join(rows) if rows else '' | ||||||
|  |      | ||||||
|     sign = "\n\n{0}\n\n```\n{1}({2})\n```".format(get_doc_desc(doc_string, function_obj), function_name, sig_content) |     sign = "\n\n{0}\n\n```\n{1}({2})\n```".format(get_doc_desc(doc_string, function_obj), function_name, sig_content) | ||||||
| 
 | 
 | ||||||
|  |      | ||||||
|  |      | ||||||
|     if is_method: |     if is_method: | ||||||
|         if insert_md_section_for__class_methods: |         if insert_md_section_for__class_methods: | ||||||
|             sign = "\n\n{0}\n\n```\n{1}({2})\n```".format(get_doc_desc(doc_string, function_obj), function_name, sig_content) |             sign = "\n\n{0}\n\n```\n{1}({2})\n```".format(get_doc_desc(doc_string, function_obj), function_name, sig_content) | ||||||
|  | @ -283,9 +292,7 @@ def get_sig_table_parts(function_obj, function_name, doc_string, | ||||||
| 
 | 
 | ||||||
|      |      | ||||||
|     # 2 |     # 2 | ||||||
|     def make_md_table_from_docstring(docstring): |     def make_md_table_from_docstring(docstring, a_original_obj): | ||||||
|         # print(f'docstring = {docstring}') |  | ||||||
|         # print(f'docstring = {type(docstring)}') |  | ||||||
|         row_n_type_regex = re.compile(r':param ([\s\S]*?):([\s\S]*?):type [\s\S]*?:([\d\D]*?)\n', flags=re.M|re.DOTALL) |         row_n_type_regex = re.compile(r':param ([\s\S]*?):([\s\S]*?):type [\s\S]*?:([\d\D]*?)\n', flags=re.M|re.DOTALL) | ||||||
|         # row_n_type_regex = re.compile(r':param ([\d\w]+):([\d\D]*?):type [\w\d]+:([\d\D].*?)$', flags=re.M|re.DOTALL) |         # row_n_type_regex = re.compile(r':param ([\d\w]+):([\d\D]*?):type [\w\d]+:([\d\D].*?)$', flags=re.M|re.DOTALL) | ||||||
| 
 | 
 | ||||||
|  | @ -325,7 +332,7 @@ def get_sig_table_parts(function_obj, function_name, doc_string, | ||||||
|         try: |         try: | ||||||
|             max_type_width, max_name_width = max([len(i.atype) for i in trips]), max([len(i.name) for i in trips]) |             max_type_width, max_name_width = max([len(i.atype) for i in trips]), max([len(i.name) for i in trips]) | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             pass |             logger.warning(f"ALERT ------ bug with max_type_width, max_name_width variables") | ||||||
|         row_template = f'| {{: ^{max_type_width}}} | {{: ^{max_name_width}}} | {{}} |' |         row_template = f'| {{: ^{max_type_width}}} | {{: ^{max_name_width}}} | {{}} |' | ||||||
| 
 | 
 | ||||||
|         # rows, and finally table. |         # rows, and finally table. | ||||||
|  | @ -342,11 +349,12 @@ def get_sig_table_parts(function_obj, function_name, doc_string, | ||||||
|             text, atype = aa.group(1).strip(), aa.group(2).strip() |             text, atype = aa.group(1).strip(), aa.group(2).strip() | ||||||
| 
 | 
 | ||||||
|             rows.append(f'| {atype} | **RETURN** | {text}') |             rows.append(f'| {atype} | **RETURN** | {text}') | ||||||
|              |  | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             print(e) |             padded_name = "{: <25}".format(f"'{a_original_obj.__name__}'") | ||||||
|             # print(f'docstring = {docstring}') | 
 | ||||||
|             pass |             logger.warning(f"ALERT ------  Hi, Mike! Please, fix ':return:' in {padded_name}" | ||||||
|  |                     " \tIF you want to see 'return' row in 'signature table'") | ||||||
|  |             # import pdb; pdb.set_trace(); | ||||||
| 
 | 
 | ||||||
|         header = '\nParameter Descriptions:\n\n|Type|Name|Meaning|\n|--|--|--|\n' |         header = '\nParameter Descriptions:\n\n|Type|Name|Meaning|\n|--|--|--|\n' | ||||||
| 
 | 
 | ||||||
|  | @ -359,8 +367,9 @@ def get_sig_table_parts(function_obj, function_name, doc_string, | ||||||
| 
 | 
 | ||||||
|     # 3 |     # 3 | ||||||
|     try: |     try: | ||||||
|         params_TABLE = md_table = make_md_table_from_docstring(doc_string) |         params_TABLE = md_table = make_md_table_from_docstring(doc_string, function_obj) | ||||||
|     except Exception as e: |     except Exception as e: | ||||||
|  |         logger.warning(f'Boy=======    We got empty md_table for "{function_obj.__name__}"') | ||||||
|         params_TABLE = md_table = '' |         params_TABLE = md_table = '' | ||||||
| 
 | 
 | ||||||
|     if not md_table.strip(): |     if not md_table.strip(): | ||||||
|  | @ -539,6 +548,8 @@ def main(do_full_readme=False, | ||||||
|     func_tags = [j for j in mark_points if 'func.' in j] |     func_tags = [j for j in mark_points if 'func.' in j] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |      | ||||||
|     # 0===0 functions 0===0 |     # 0===0 functions 0===0 | ||||||
|     for tag in func_tags: |     for tag in func_tags: | ||||||
| 
 | 
 | ||||||
|  | @ -576,6 +587,7 @@ def main(do_full_readme=False, | ||||||
|                 logger.error(f' General error in parsing function tag: tag = "{tag}"; error="{str(e)}"') |                 logger.error(f' General error in parsing function tag: tag = "{tag}"; error="{str(e)}"') | ||||||
|             continue |             continue | ||||||
| 
 | 
 | ||||||
|  |     injection_points.append('now, classes.') | ||||||
|     # 0===0 classes 0===0 |     # 0===0 classes 0===0 | ||||||
|     for tag in classes_method_tags: |     for tag in classes_method_tags: | ||||||
|         try: |         try: | ||||||
|  | @ -637,25 +649,27 @@ def main(do_full_readme=False, | ||||||
|     # 8888888888888888888888888888888888888888888888888888888 |     # 8888888888888888888888888888888888888888888888888888888 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |     bar_it = lambda x: '\n' + '='*len(x) + f'\nSTARTING TO INSERT markdown text into 2_readme.md\n' + '='*len(x) + '\n' | ||||||
|     # 1> log some data |     # 1> log some data | ||||||
|     success_tags = [] |     success_tags = [] | ||||||
|     bad_tags = [] |     bad_tags = [] | ||||||
|     for injection in injection_points: |     for injection in injection_points: | ||||||
|  |         if injection == 'now, classes.': | ||||||
|  |             logger.info(bar_it('STARTING TO INSERT markdown text into 2_readme.md')) | ||||||
|  |             continue | ||||||
|          |          | ||||||
|         # SPECIAL CASE: X.doc tag |         # SPECIAL CASE: X.doc tag | ||||||
|         if injection['part2'] == 'doc': |         if injection['part2'] == 'doc': | ||||||
|             a_tag = injection['tag'] |             a_tag = injection['tag'] | ||||||
|             print(f'a_tag = {a_tag}') |             logger.info(f'a_tag = {a_tag, type(a_tag).__name__}') | ||||||
|             print(f'a_tag = {type(a_tag)}') |  | ||||||
|             doc_ = '' if not injection['parent_class'].__doc__ else injection['parent_class'].__doc__ |             doc_ = '' if not injection['parent_class'].__doc__ else injection['parent_class'].__doc__ | ||||||
|             # if doc_ == None or a_tag == None: |             # if doc_ == None or a_tag == None: | ||||||
|             #     import pdb; pdb.set_trace(); |              | ||||||
|                  |                  | ||||||
|             readme = readme.replace(a_tag, doc_) |             readme = readme.replace(a_tag, doc_) | ||||||
|          |          | ||||||
|         else: |         else: | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|             content = render(injection, logger=logger, line_break=line_break, |             content = render(injection, logger=logger, line_break=line_break, | ||||||
|                 insert_md_section_for__class_methods=insert_md_section_for__class_methods) |                 insert_md_section_for__class_methods=insert_md_section_for__class_methods) | ||||||
|          |          | ||||||
|  | @ -667,6 +681,7 @@ def main(do_full_readme=False, | ||||||
| 
 | 
 | ||||||
|             readme = readme.replace(tag, content) |             readme = readme.replace(tag, content) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|     bad_part = '''\n\nParameter Descriptions:\n\n|Type|Name|Meaning|\n|--|--|--|\n\n''' |     bad_part = '''\n\nParameter Descriptions:\n\n|Type|Name|Meaning|\n|--|--|--|\n\n''' | ||||||
|     readme = readme.replace(bad_part, '\n') |     readme = readme.replace(bad_part, '\n') | ||||||
| 
 | 
 | ||||||
|  | @ -683,8 +698,6 @@ def main(do_full_readme=False, | ||||||
|         logger.info(good_message) |         logger.info(good_message) | ||||||
|         logger.info(bad_message) |         logger.info(bad_message) | ||||||
| 
 | 
 | ||||||
|     print(123) |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
|     # 8888888888888888888888888888888888 |     # 8888888888888888888888888888888888 | ||||||
|     # ===========  6 join  =========== # |     # ===========  6 join  =========== # | ||||||
|  | @ -733,8 +746,8 @@ def main(do_full_readme=False, | ||||||
|             if remove_repeated_sections_classmethods: |             if remove_repeated_sections_classmethods: | ||||||
|                 rega = re.compile(r'((\#+\s\w+)\n\s){2}', flags=re.MULTILINE) |                 rega = re.compile(r'((\#+\s\w+)\n\s){2}', flags=re.MULTILINE) | ||||||
|                 for index, i in enumerate(re.finditer(rega, content)): |                 for index, i in enumerate(re.finditer(rega, content)): | ||||||
|                     print(f'{index} - > {i.group(0)}') |                     logger.info(f'{index} - > {i.group(0)}') | ||||||
|                     print(f'{index} - > {i.group(1)}') |                     logger.info(f'{index} - > {i.group(1)}') | ||||||
|                     content = content.replace(i.group(0), i.group(1)) |                     content = content.replace(i.group(0), i.group(1)) | ||||||
|                 # re |                 # re | ||||||
|                 # content = re.sub(rega, r'\1', content, flags=re.MULTILINE) |                 # content = re.sub(rega, r'\1', content, flags=re.MULTILINE) | ||||||
|  | @ -750,6 +763,9 @@ def main(do_full_readme=False, | ||||||
|     if logger: |     if logger: | ||||||
|         logger.error(f'Error in main') |         logger.error(f'Error in main') | ||||||
| 
 | 
 | ||||||
|  |     logger.save_messages() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| @click.command() | @click.command() | ||||||
| @click.option('-nol', '--no_log',                   is_flag=True, help='Disable log') | @click.option('-nol', '--no_log',                   is_flag=True, help='Disable log') | ||||||
|  | @ -772,7 +788,6 @@ def cli(no_log, delete_log, delete_html_comments, output_name, log_file): | ||||||
|     my_file = logging.FileHandler(log_file, mode='w') |     my_file = logging.FileHandler(log_file, mode='w') | ||||||
|     my_file.setLevel(logging.DEBUG) |     my_file.setLevel(logging.DEBUG) | ||||||
|     formatter = logging.Formatter('%(asctime)s>%(levelname)s: %(message)s') |     formatter = logging.Formatter('%(asctime)s>%(levelname)s: %(message)s') | ||||||
| 
 |  | ||||||
|     my_file.setFormatter(formatter) |     my_file.setFormatter(formatter) | ||||||
|     logger.addHandler(my_file) |     logger.addHandler(my_file) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,17 @@ | ||||||
|  | import datetime,time,os | ||||||
|  | cd = CD = os.path.dirname(os.path.abspath(__file__)) | ||||||
|  | 
 | ||||||
| from make_real_readme import main | from make_real_readme import main | ||||||
|  | def readfile(filename): | ||||||
|  |     with open(filename, 'r', encoding='utf-8') as ff: return ff.read() | ||||||
|  | def writefile(fpath, content): | ||||||
|  |     with open(fpath, 'w', encoding='utf-8') as ff: ff.write(content) | ||||||
|  | import json | ||||||
|  | def writejson(a_path:str, a_dict:dict) -> None: | ||||||
|  |     with open(a_path, 'w', encoding='utf-8') as output_file: | ||||||
|  |         json.dump(a_dict, output_file, ensure_ascii=False, indent=2) | ||||||
|  | def readjson(a_path:str) -> dict: | ||||||
|  |     with open(a_path, 'r', encoding='utf-8') as f: return json.load(f) | ||||||
| 
 | 
 | ||||||
| ######################################################################## | ######################################################################## | ||||||
| #                              __ _            _                       # | #                              __ _            _                       # | ||||||
|  | @ -60,25 +73,138 @@ if method == 'simple, no log': | ||||||
| #     / /_     # | #     / /_     # | ||||||
| #    |____|    # | #    |____|    # | ||||||
| ################ | ################ | ||||||
| if method == 'with logs': | class BESTLOG(object): | ||||||
|  |     def __init__(self, filename): | ||||||
|  |         # my_file = logging.FileHandler(filename, mode='w') | ||||||
|  |         # my_file.setLevel(logging.DEBUG) | ||||||
|  |         # my_file.setFormatter(logging.Formatter('%(asctime)s>%(levelname)s: %(message)s')) | ||||||
|  |         # logger = logging.getLogger(__name__) | ||||||
|  |         # logger.setLevel(logging.DEBUG) | ||||||
|  |         # logger.addHandler(my_file) | ||||||
|  |         self.filename = filename | ||||||
|  |         self.json_name = filename + '.json' | ||||||
|  |         self.error_list = [] | ||||||
|  |         self.warning_list = [] | ||||||
|  |         self.info_list = [] | ||||||
|  |         self.debug_list = [] | ||||||
|  |         self.tick_amount=1 | ||||||
|  |         self.names = self.messages_names = 'error warning info debug'.split(' ') | ||||||
| 
 | 
 | ||||||
|     import logging |     def tick(self): | ||||||
|     logger = logging.getLogger(__name__) |         self.tick_amount+=1 | ||||||
|     logger.setLevel(logging.DEBUG) |         return self.tick_amount | ||||||
| 
 | 
 | ||||||
|     my_file = logging.FileHandler('usage.log.txt', mode='w') |     ####################################################################### | ||||||
|     my_file.setLevel(logging.DEBUG) |     #      __             _                             _ _               # | ||||||
|     formatter = logging.Formatter('%(asctime)s>%(levelname)s: %(message)s') |     #     / _|           | |                           (_) |              # | ||||||
|     my_file.setFormatter(formatter) |     #    | |_ ___  _ __  | |_ _ __ __ _ _ __  ___ _ __  _| | ___ _ __     # | ||||||
|     logger.addHandler(my_file) |     #    |  _/ _ \| '__| | __| '__/ _` | '_ \/ __| '_ \| | |/ _ \ '__|    # | ||||||
|     logger.info('STARTING') |     #    | || (_) | |    | |_| | | (_| | | | \__ \ |_) | | |  __/ |       # | ||||||
|  |     #    |_| \___/|_|     \__|_|  \__,_|_| |_|___/ .__/|_|_|\___|_|       # | ||||||
|  |     #                                            | |                      # | ||||||
|  |     #                                            |_|                      # | ||||||
|  |     ####################################################################### | ||||||
|  |     def error(self, m):     self.error_list.append([self.tick(), m]) | ||||||
|  |     def warning(self, m):   self.warning_list.append([self.tick(), m]) | ||||||
|  |     def info(self, m):      self.info_list.append([self.tick(), m]) | ||||||
|  |     def debug(self, m):     self.debug_list.append([self.tick(), m]) | ||||||
| 
 | 
 | ||||||
|     main(logger=logger, |     ########################################## | ||||||
|  |     #      __                                # | ||||||
|  |     #     / _|                               # | ||||||
|  |     #    | |_ ___  _ __   _ __ ___   ___     # | ||||||
|  |     #    |  _/ _ \| '__| | '_ ` _ \ / _ \    # | ||||||
|  |     #    | || (_) | |    | | | | | |  __/    # | ||||||
|  |     #    |_| \___/|_|    |_| |_| |_|\___|    # | ||||||
|  |     #                                        # | ||||||
|  |     #                                        # | ||||||
|  |     ########################################## | ||||||
|  |     def tolist(self):    return zip([self.error_list, self.warning_list, self.info_list, self.debug_list], self.names) | ||||||
|  |     def todict(self):    return {'error' : self.error_list, 'warning' : self.warning_list, 'info' : self.info_list, 'debug' : self.debug_list} | ||||||
|  |      | ||||||
|  |     def save(self): | ||||||
|  |         all_messages_list = [] | ||||||
|  |         for messages, message_type in self.tolist(): | ||||||
|  |             all_messages_list.extend([{'message_type' : message_type, 'message_text' : m_text, 'message_time' : m_time} for m_time, m_text in messages]) | ||||||
|  | 
 | ||||||
|  |         # sort messages on time | ||||||
|  |         all_messages_list = sorted(all_messages_list, key=lambda x: x['message_time']) | ||||||
|  |          | ||||||
|  |         # convert time | ||||||
|  |         # for i in all_messages_list: i['message_time'] = i['message_time'].strftime('%Y-%m-%d %H:%M:%S.%f') | ||||||
|  | 
 | ||||||
|  |         writejson(self.json_name, all_messages_list) | ||||||
|  |     def load(self, **kw): | ||||||
|  |         ''' | ||||||
|  |             return dict with messages | ||||||
|  |              | ||||||
|  |             kw = { | ||||||
|  |                 use_psg_color : bool | ||||||
|  |                 show_time : bool | ||||||
|  |             } | ||||||
|  |         ''' | ||||||
|  | 
 | ||||||
|  |         # plan: | ||||||
|  |         # read json, convert time | ||||||
|  | 
 | ||||||
|  |         # read | ||||||
|  |         all_messages_list = readjson(self.json_name) | ||||||
|  |         # convert time | ||||||
|  |         # for i in all_messages_list: i['message_time'] = datetime.datetime.strptime(i['message_time'], '%Y-%m-%d %H:%M:%S.%f') | ||||||
|  | 
 | ||||||
|  |         def format_message(message): | ||||||
|  |             if kw['show_time']: | ||||||
|  |                 return str(message['message_time']) + ':' + message['message_text']  | ||||||
|  |             else: | ||||||
|  |                 return message['message_text'] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         #=========# | ||||||
|  |         # 4 lists # | ||||||
|  |         #=========# | ||||||
|  |         error_list =   [i for i in all_messages_list if i['message_type'] == 'error'] | ||||||
|  |         warning_list = [i for i in all_messages_list if i['message_type'] == 'warning'] | ||||||
|  |         info_list =    [i for i in all_messages_list if i['message_type'] == 'info'] | ||||||
|  |         debug_list =   [i for i in all_messages_list if i['message_type'] == 'debug'] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         #=================# | ||||||
|  |         # and 1 more list # | ||||||
|  |         #=================# | ||||||
|  |         colors = {'warning' : 'magenta', 'info' : 'black'} | ||||||
|  |         warning_info_ = [] | ||||||
|  |         for message in sorted(warning_list + info_list, key=lambda x: x['message_time']): | ||||||
|  |             if kw['use_psg_color']: | ||||||
|  |                 warning_info_.append([   format_message(message), | ||||||
|  |                                         colors.get(message['message_type'])    ]) | ||||||
|  |             else: | ||||||
|  |                 warning_info_.append(format_message(message)) | ||||||
|  | 
 | ||||||
|  |         error_list = map(format_message, error_list) | ||||||
|  |         warning_list = map(format_message, warning_list) | ||||||
|  |         info_list = map(format_message, info_list) | ||||||
|  |         debug_list = map(format_message, debug_list) | ||||||
|  | 
 | ||||||
|  |         return error_list, warning_list, info_list, debug_list, warning_info_ | ||||||
|  | 
 | ||||||
|  | def compile_all_stuff(**kw): | ||||||
|  |     # import logging | ||||||
|  | 
 | ||||||
|  |     log_file = os.path.join(cd, 'LoG') | ||||||
|  |     log_obj = BESTLOG(log_file) | ||||||
|  |     main(logger=log_obj, | ||||||
|          insert_md_section_for__class_methods=insert_md_section_for__class_methods, |          insert_md_section_for__class_methods=insert_md_section_for__class_methods, | ||||||
|          remove_repeated_sections_classmethods=remove_repeated_sections_classmethods, |          remove_repeated_sections_classmethods=remove_repeated_sections_classmethods, | ||||||
|          files_to_include=[0, 1, 2, 3], |          files_to_include=[0, 1, 2, 3], | ||||||
|          output_name=OUTPUT_FILENAME, |          output_name=OUTPUT_FILENAME, | ||||||
|          delete_html_comments=True) |          delete_html_comments=True) | ||||||
|  |     log_obj.save() | ||||||
|  | 
 | ||||||
|  |     # cd = CD = os.path.dirname(os.path.abspath(__file__)) | ||||||
|  |     # log_file = os.path.join(cd, 'usage.log.txt') | ||||||
|  |     return log_obj.load(**kw) | ||||||
|  | 
 | ||||||
|  | # if method == 'with logs': compile_all_stuff() | ||||||
| 
 | 
 | ||||||
| ######################################## | ######################################## | ||||||
| #     _____                            # | #     _____                            # | ||||||
|  | @ -90,9 +216,76 @@ if method == 'with logs': | ||||||
| #               | |         | |        # | #               | |         | |        # | ||||||
| #               |_|         |_|        # | #               |_|         |_|        # | ||||||
| ######################################## | ######################################## | ||||||
|  | def mini_GUI(): | ||||||
|  |     my_font = ("Helvetica", 12) | ||||||
|  |     my_font2 = ("Helvetica", 12, "bold") | ||||||
|  |     my_font3 = ("Helvetica", 15, "bold") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     layout = [ | ||||||
|  |        [ | ||||||
|  |            sg.Column(layout=[ | ||||||
|  |                 [sg.T('debug', font=my_font, text_color='blue')], | ||||||
|  |                 [sg.ML(size=(70-15,20), key='debug')], | ||||||
|  |                 [sg.T('error', font=my_font, text_color='red')], | ||||||
|  |                 [sg.ML(size=(70-15,20), key='error')], | ||||||
|  |             ]) | ||||||
|  |            ,sg.T('            ') | ||||||
|  |            ,sg.Column(layout=[ | ||||||
|  |                 [sg.T('warning', font=my_font2)], | ||||||
|  |                 [sg.ML(size=(70-12,20), key='warning')], | ||||||
|  |                 [sg.T('info', font=my_font2)], | ||||||
|  |                 [sg.ML(size=(70-12,20), key='info')], | ||||||
|  |             ]), | ||||||
|  |            sg.Column(layout=[ | ||||||
|  |                 [sg.T('warning_info', font=my_font3)], | ||||||
|  |                 [sg.ML(size=(110,42), key='warning_info')], | ||||||
|  |             ]), | ||||||
|  |             | ||||||
|  |         ] | ||||||
|  |     ] | ||||||
|  |     window = sg.Window('We are live! Again! --- ' + 'Completed making {}'.format(OUTPUT_FILENAME), [ | ||||||
|  |         [sg.T(size=(25,1), font=my_font, key='-compile-time-')] | ||||||
|  |         ,[   | ||||||
|  |             sg.B('Run again (F1)', key='-run-') | ||||||
|  |             ,sg.CB('show time in logs (F2)', False, key='show_time') | ||||||
|  |             ,sg.CB('Logs with Color (F3)', True, key='use_psg_color') | ||||||
|  |         ] | ||||||
|  |         ,*layout | ||||||
|  |     ], resizable=True, finalize=True, location=(0,0), return_keyboard_events = True) | ||||||
|  | 
 | ||||||
|  |     def update_compilation_in_psg(values): | ||||||
|  |         # get results | ||||||
|  |         results = compile_all_stuff(use_psg_color=values['use_psg_color'], show_time=values['show_time']) | ||||||
|  | 
 | ||||||
|  |         # UPDATE GUI | ||||||
|  |         curr_time = lambda : datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S.%f') | ||||||
|  |         window['-compile-time-'](curr_time()) | ||||||
|  |         for key, txt in zip('error warning info debug'.split(' '), results[:4]): | ||||||
|  |             window[key]('\n'.join(txt)) | ||||||
|  |         # colors warning_info | ||||||
|  |         window['warning_info'].update('') | ||||||
|  |         if values['use_psg_color']: | ||||||
|  |             for text, color in results[-1]: | ||||||
|  |                 window['warning_info'].print(text, text_color=color) | ||||||
|  |         else: | ||||||
|  |             window['warning_info']('\n'.join(results[-1])) | ||||||
|  | 
 | ||||||
|  |     update_compilation_in_psg({'use_psg_color':not False, 'show_time':False}) | ||||||
|  |     while True: | ||||||
|  |         event, values = window() | ||||||
|  |         if event in ('Exit', None): break | ||||||
|  | 
 | ||||||
|  |         # print(event) | ||||||
|  |         if event == '-run-' or 'F1' in event: update_compilation_in_psg(values) | ||||||
|  |         if 'F2' in event: window['show_time'](not values['show_time']) | ||||||
|  |         if 'F3' in event: window['use_psg_color'](not values['use_psg_color']) | ||||||
|  | 
 | ||||||
|  |     window.close() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| if enable_popup: | if enable_popup: | ||||||
|     import PySimpleGUI as sg |     import PySimpleGUI as sg | ||||||
|     lines = open('usage.log.txt', mode='r').readlines() |  | ||||||
|     sg.PopupScrolled('Completed making {}'.format(OUTPUT_FILENAME), ''.join(lines), size=(80,50)) |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
|  |     mini_GUI() | ||||||
|  |     # sg.PopupScrolled('Completed making {}'.format(OUTPUT_FILENAME), ''.join(lines), size=(80,50)) | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| import inspect | import PySimpleGUIlib;sg = PySimpleGUIlib | ||||||
| import PySimpleGUIlib | import datetime, inspect | ||||||
| 
 | 
 | ||||||
| """  | """  | ||||||
|     Create All Possible Tags |     Create All Possible Tags | ||||||
|  | @ -8,12 +8,8 @@ import PySimpleGUIlib | ||||||
|     Displays the results in a PySimpleGUI window which can be used to copy and paste into other places. |     Displays the results in a PySimpleGUI window which can be used to copy and paste into other places. | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
| layout = [[PySimpleGUIlib.Output(size=(80,40))]] | messages = []; log = lambda x: messages.append(x) # logging utility | ||||||
| window = PySimpleGUIlib.Window('Dump of tags', layout, resizable=True).Finalize() | SHOW_functionsNmethods_that_starts_with_UNDERSCORE = True | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| SHOW_UNDERSCORE_METHODS = not False |  | ||||||
| 
 | 
 | ||||||
| def valid_field(pair): | def valid_field(pair): | ||||||
|     bad_fields = 'LOOK_AND_FEEL_TABLE copyright __builtins__'.split(' ') |     bad_fields = 'LOOK_AND_FEEL_TABLE copyright __builtins__'.split(' ') | ||||||
|  | @ -29,10 +25,13 @@ def valid_field(pair): | ||||||
| 
 | 
 | ||||||
|     return True |     return True | ||||||
| 
 | 
 | ||||||
| psg_members  = [i for i in inspect.getmembers(PySimpleGUIlib) if valid_field(i)] | 
 | ||||||
| psg_funcs    = [o[0] for o in psg_members if inspect.isfunction(o[1])] | #                                                                                       # ] | ||||||
| psg_classes  = [o for o in psg_members if inspect.isclass(o[1])] | psg_members  = [i for i in inspect.getmembers(PySimpleGUIlib) if valid_field(i)]        # ]  | ||||||
| # psg_props    = [o for o in psg_members if type(o[1]).__name__ == 'property'] | psg_funcs    = [o[0] for o in psg_members if inspect.isfunction(o[1])]                  # ] Grabing PSG objects | ||||||
|  | psg_classes  = [o for o in psg_members if inspect.isclass(o[1])]                        # ]  | ||||||
|  | # psg_props    = [o for o in psg_members if type(o[1]).__name__ == 'property']          # ] | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| # I don't know how this magic filtering works, I just know it works. "Private" stuff (begins with _) are somehow | # I don't know how this magic filtering works, I just know it works. "Private" stuff (begins with _) are somehow | ||||||
| # excluded from the list with the following 2 lines of code.  Very nicely done Kol-ee-ya! | # excluded from the list with the following 2 lines of code.  Very nicely done Kol-ee-ya! | ||||||
|  | @ -40,24 +39,62 @@ psg_classes = sorted(list(set([i[1] for i in psg_classes])), key=lambda x : x.__ | ||||||
| 
 | 
 | ||||||
| for aclass in psg_classes: | for aclass in psg_classes: | ||||||
|     class_name = aclass.__name__ |     class_name = aclass.__name__ | ||||||
|     if 'Tk' in class_name or 'TK' in class_name or 'Element' == class_name: # or 'Window' == class_name: |      | ||||||
|  |     # filter bad objects | ||||||
|  |     if  'Tk' in class_name or 'TK' in class_name or\ | ||||||
|  |         'Element' == class_name: # or 'Window' == class_name: | ||||||
|         continue |         continue | ||||||
|     print(f'### {class_name} Element ') |  | ||||||
|     print(f'<!-- <+{class_name}.doc+> -->') |  | ||||||
|     print(f'<!-- <+{class_name}.__init__+> -->\n') |  | ||||||
|     print('\n'.join([f"#### {name}\n<!-- <+{class_name}.{name}+> -->\n" for name, obj in inspect.getmembers(aclass) if not name.startswith('_')  ])) |  | ||||||
|      |      | ||||||
| print('\n------------------------- Functions start here -------------------------\n') |     # print standart things: | ||||||
|  |     log(f'### {class_name} Element ') | ||||||
|  |     log(f'<!-- <+{class_name}.doc+> -->') | ||||||
|  |     log(f'<!-- <+{class_name}.__init__+> -->\n') | ||||||
| 
 | 
 | ||||||
| if SHOW_UNDERSCORE_METHODS: |     # print all public methods: | ||||||
|  |     log('\n'.join([f"#### {name}\n<!-- <+{class_name}.{name}+> -->\n" | ||||||
|  |                     for name, obj in inspect.getmembers(aclass) | ||||||
|  |                     if not name.startswith('_')  ])) | ||||||
|  | 
 | ||||||
|  | def get_filtered_funcs(psg_funcs, show_underscore=False): | ||||||
|  |     space = '-'*30 | ||||||
|  |     curr_dt = today = datetime.datetime.today() | ||||||
|  |     filtered = [f'{curr_dt}\n\n{space}Functions start here{space}\n'] | ||||||
|     for i in psg_funcs: |     for i in psg_funcs: | ||||||
|         if '_' in i: |         txt = f"<!-- <+func.{i}+> -->" | ||||||
|             print( f"<!-- <+func.{i}+> -->" ) | 
 | ||||||
| else: |         if i.startswith('_') and show_underscore: | ||||||
|     for i in psg_funcs: |             filtered.append(txt); continue | ||||||
|         print( f"<!-- <+func.{i}+> -->" ) |         filtered.append(txt) | ||||||
|  |     return f'TOTAL funcs amount listed below: {len(filtered)}\n' + '\n'.join(filtered) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | ############################### | ||||||
|  | #      _____ _    _ _____     # | ||||||
|  | #     / ____| |  | |_   _|    # | ||||||
|  | #    | |  __| |  | | | |      # | ||||||
|  | #    | | |_ | |  | | | |      # | ||||||
|  | #    | |__| | |__| |_| |_     # | ||||||
|  | #     \_____|\____/|_____|    # | ||||||
|  | #                             # | ||||||
|  | ############################### | ||||||
|  | window = sg.Window('Dump of tags', [ | ||||||
|  |     [sg.ML(size=(80,40), key='w'), | ||||||
|  |     sg.Col([ | ||||||
|  |             [sg.ML(size=(80,40), key='w2')], | ||||||
|  |             [sg.CB('show _ funcs&methods?', key='-_sc-', enable_events=True)] | ||||||
|  |         ])] | ||||||
|  | ], resizable=True, finalize=True) | ||||||
| 
 | 
 | ||||||
|  | window['w']('\n'.join(messages)) | ||||||
|  | window['w2'](get_filtered_funcs(psg_funcs, True)) | ||||||
| 
 | 
 | ||||||
| window.Read() | while True: | ||||||
|  |     event, values = window() | ||||||
|  |     if event in ('Exit', None): break | ||||||
|  | 
 | ||||||
|  |     print(event) | ||||||
|  |     if event == '-_sc-': | ||||||
|  |         filtered = get_filtered_funcs(psg_funcs, values['-_sc-']) | ||||||
|  |         window['w2'](filtered) | ||||||
|  | 
 | ||||||
|  | window.close() | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue