2020-06-28 13:59:09 +00:00
import re , datetime , time , os , platform , json , PySimpleGUI as sg ; from subprocess import Popen ; from make_real_readme import main
cd = os . path . dirname ( os . path . abspath ( __file__ ) )
2020-05-16 01:15:57 +00:00
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 )
def writejson ( a_path : str , a_dict : dict ) - > None :
2020-06-28 13:59:09 +00:00
with open ( a_path , ' w ' , encoding = ' utf-8 ' ) as output_file : json . dump ( a_dict , output_file , ensure_ascii = False , indent = 2 )
2020-05-16 01:15:57 +00:00
def readjson ( a_path : str ) - > dict :
with open ( a_path , ' r ' , encoding = ' utf-8 ' ) as f : return json . load ( f )
2019-07-26 23:35:16 +00:00
2020-06-28 13:59:09 +00:00
def openfile ( a_path ) :
# File exists?
if not os . path . exists ( a_path ) : return sg . Popup ( f " Error! This file doesn ' t exists: { a_path } " )
# check: OS
if ' Windows ' in platform . system ( ) :
os . startfile ( a_path )
elif ' Linux ' in platform . system ( ) :
Popen ( f ' exo-open " { a_path } " ' , shell = True )
def opendir ( a_path ) :
# Folder exists?
if not os . path . exists ( a_path ) : return sg . Popup ( f " Error! This directory doesn ' t exists: { a_path } " )
# check: OS
if ' Windows ' in platform . system ( ) :
os . startfile ( a_path )
elif ' Linux ' in platform . system ( ) :
Popen ( f ' exo-open --launch FileManager --working-directory " { a_path } " ' , shell = True )
2019-07-26 23:35:16 +00:00
########################################################################
# __ _ _ #
# / _(_) | | #
# __ __ ___ ___ _ __ | |_ _ __ _ | |__ ___ _ __ ___ #
# \ \ / / / __/ _ \| '_ \| _| |/ _` | | '_ \ / _ \ '__/ _ \ #
# \ V / | (_| (_) | | | | | | | (_| | | | | | __/ | | __/ #
# \_/ \___\___/|_| |_|_| |_|\__, | |_| |_|\___|_| \___| #
# __/ | #
# |___/ #
########################################################################
2020-06-28 13:59:09 +00:00
def load_configs ( ) : return readjson ( os . path . join ( cd , ' app_configs.json ' ) )
def save_configs ( a_config : dict ) : writejson ( os . path . join ( cd , ' app_configs.json ' ) , a_config )
2019-07-26 23:35:16 +00:00
2020-06-28 13:59:09 +00:00
APP_CONFIGS = load_configs ( )
README_OFILENAME = APP_CONFIGS [ ' README_FILENAME ' ]
CALL_REFERENCE_OFILENAME = APP_CONFIGS [ ' CALL_REFERENCE_FILENAME ' ]
2019-07-26 23:35:16 +00:00
##-#-#-# ##-#-#-#
# Post-process logic
##-#-#-# ##-#-#-#
insert_md_section_for__class_methods = False
remove_repeated_sections_classmethods = False
2020-05-16 01:15:57 +00:00
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 ( ' ' )
def tick ( self ) :
self . tick_amount + = 1
return self . tick_amount
#######################################################################
# __ _ _ _ #
# / _| | | (_) | #
# | |_ ___ _ __ | |_ _ __ __ _ _ __ ___ _ __ _| | ___ _ __ #
# | _/ _ \| '__| | __| '__/ _` | '_ \/ __| '_ \| | |/ _ \ '__| #
# | || (_) | | | |_| | | (_| | | | \__ \ |_) | | | __/ | #
# |_| \___/|_| \__|_| \__,_|_| |_|___/ .__/|_|_|\___|_| #
# | | #
# |_| #
#######################################################################
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 ] )
##########################################
# __ #
# / _| #
# | |_ ___ _ __ _ __ ___ ___ #
# | _/ _ \| '__| | '_ ` _ \ / _ \ #
# | || (_) | | | | | | | | __/ #
# |_| \___/|_| |_| |_| |_|\___| #
# #
# #
##########################################
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 }
2019-07-26 23:35:16 +00:00
2020-05-16 01:15:57 +00:00
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_
2020-06-28 13:59:09 +00:00
def compile_call_ref ( output_filename = ' output/LoG_call_ref ' , * * kw ) :
''' Compile a " 5_call_reference.md " file '''
2020-05-16 01:15:57 +00:00
2020-06-28 13:59:09 +00:00
log_obj = BESTLOG ( os . path . join ( cd , output_filename ) )
2020-05-16 01:15:57 +00:00
main ( logger = log_obj ,
2020-06-28 13:59:09 +00:00
main_md_file = ' markdown input files/5_call_reference.md ' ,
2019-07-26 23:35:16 +00:00
insert_md_section_for__class_methods = insert_md_section_for__class_methods ,
remove_repeated_sections_classmethods = remove_repeated_sections_classmethods ,
2020-06-28 13:59:09 +00:00
files_to_include = [ ] ,
output_name = CALL_REFERENCE_OFILENAME ,
2019-07-26 23:35:16 +00:00
delete_html_comments = True )
2020-05-16 01:15:57 +00:00
log_obj . save ( )
2020-06-28 13:59:09 +00:00
return log_obj . load ( * * kw )
2020-05-16 01:15:57 +00:00
2020-06-28 13:59:09 +00:00
def compile_readme ( output_filename = ' output/LoG ' , * * kw ) :
''' Compile a " 2_readme.md " file '''
log_obj = BESTLOG ( os . path . join ( cd , output_filename ) )
main ( logger = log_obj ,
insert_md_section_for__class_methods = insert_md_section_for__class_methods ,
remove_repeated_sections_classmethods = remove_repeated_sections_classmethods ,
files_to_include = [ 0 , 1 , 2 , 3 ] ,
output_name = README_OFILENAME ,
delete_html_comments = True )
log_obj . save ( )
2020-05-16 01:15:57 +00:00
return log_obj . load ( * * kw )
2020-06-28 13:59:09 +00:00
def compile_all_stuff ( * * kw ) :
'''
Compile a " 2_ and 5_ " . md filess
return output from them
'''
result_readme = compile_readme ( * * kw )
result_call_ref = compile_call_ref ( * * kw )
return result_readme , result_call_ref
2019-07-26 23:35:16 +00:00
########################################
# _____ #
# | __ \ #
# | |__) |__ _ __ _ _ _ __ #
# | ___/ _ \| '_ \| | | | '_ \ #
# | | | (_) | |_) | |_| | |_) | #
# |_| \___/| .__/ \__,_| .__/ #
# | | | | #
# |_| |_| #
########################################
2020-06-28 13:59:09 +00:00
def md2psg ( target_text ) :
# target = 'This is **bold** and *italic* words'
# V
# sg.T('This is '), sg.T('bold', font=...bold), ...'
# imports
from collections import namedtuple
spec = namedtuple ( ' spec ' , ' char text ' . split ( ' ' ) )
# START
# =====
parts = re . compile ( r ' ([ \ *] { 1,2})([ \ s \ S]*?)([ \ *] { 1,2}) ' , flags = re . M | re . DOTALL ) . split ( target_text )
chuncks , skip_this = [ ] , 0
for index , part in enumerate ( parts ) :
if skip_this != 0 :
skip_this - = 1 ; continue
if part not in [ ' * ' , ' ** ' ] : chuncks . append ( part )
else :
skip_this = 2
chuncks . append ( spec ( part , parts [ index + 1 ] ) )
font_norm = ( ' Mono 13 ' ) # (*sg.DEFAULT_FONT, 'italic')
font_bold = ( ' Mono 13 italic ' ) # (*sg.DEFAULT_FONT, 'italic')
font_ita = ( ' Mono 13 bold ' ) # (*sg.DEFAULT_FONT, 'bold')
list_of_Ts = [ ]
for chunck in chuncks :
if type ( chunck ) is str : list_of_Ts . append ( sg . T ( chunck , font = font_norm , size = ( len ( chunck ) , 1 ) , pad = ( 0 , 0 ) ) )
elif type ( chunck ) is spec :
if chunck . char == ' * ' : list_of_Ts . append ( sg . T ( chunck . text , font = font_ita , pad = ( 0 , 0 ) , size = ( len ( chunck . text ) , 1 ) ) )
if chunck . char == ' ** ' : list_of_Ts . append ( sg . T ( chunck . text , font = font_bold , pad = ( 0 , 0 ) , size = ( len ( chunck . text ) , 1 ) ) )
return list_of_Ts
2020-05-16 01:15:57 +00:00
def mini_GUI ( ) :
my_font = ( " Helvetica " , 12 )
my_font2 = ( " Helvetica " , 12 , " bold " )
my_font3 = ( " Helvetica " , 15 , " bold " )
2020-06-28 13:59:09 +00:00
my_font4 = ( " Mono " , 18 , " bold " )
2020-05-16 01:15:57 +00:00
2020-06-28 13:59:09 +00:00
def make_tab ( word ) :
return [ [
sg . Column ( layout = [
2020-05-16 01:15:57 +00:00
[ sg . T ( ' debug ' , font = my_font , text_color = ' blue ' ) ] ,
2020-06-28 13:59:09 +00:00
[ sg . ML ( size = ( 70 - 15 , 15 ) , key = f ' - { word } -debug- ' ) ] ,
2020-05-16 01:15:57 +00:00
[ sg . T ( ' error ' , font = my_font , text_color = ' red ' ) ] ,
2020-06-28 13:59:09 +00:00
[ sg . ML ( size = ( 70 - 15 , 15 ) , key = f ' - { word } -error- ' ) ] ,
] ) ,
sg . T ( ' ' ) , sg . Column ( layout = [
2020-05-16 01:15:57 +00:00
[ sg . T ( ' warning ' , font = my_font2 ) ] ,
2020-06-28 13:59:09 +00:00
[ sg . ML ( size = ( 70 - 12 , 15 ) , key = f ' - { word } -warning- ' ) ] ,
2020-05-16 01:15:57 +00:00
[ sg . T ( ' info ' , font = my_font2 ) ] ,
2020-06-28 13:59:09 +00:00
[ sg . ML ( size = ( 70 - 12 , 15 ) , key = f ' - { word } -info- ' ) ] ,
2020-05-16 01:15:57 +00:00
] ) ,
2020-06-28 13:59:09 +00:00
sg . Column ( layout = [
2020-05-16 01:15:57 +00:00
[ sg . T ( ' warning_info ' , font = my_font3 ) ] ,
2020-06-28 13:59:09 +00:00
[ sg . ML ( size = ( 110 , 42 - 8 ) , key = f ' - { word } -warning_info- ' ) ] ,
2020-05-16 01:15:57 +00:00
] ) ,
2020-06-28 13:59:09 +00:00
] ]
layout = [
[ sg . TabGroup ( [ [
sg . Tab ( ' README ' , make_tab ( ' README ' ) ) ,
sg . Tab ( ' CALL_REF ' , make_tab ( ' CALL_REF ' ) )
] ]
)
2020-05-16 01:15:57 +00:00
]
]
2020-06-28 13:59:09 +00:00
window = sg . Window ( ' We are live! Again! --- ' + ' Completed making {} , {} ' . format ( os . path . basename ( README_OFILENAME ) , os . path . basename ( CALL_REFERENCE_OFILENAME ) ) , [
[ sg . T ( size = ( 25 , 1 ) , font = my_font , key = ' -compile-time- ' ) ] ,
[ sg . T ( f ' The PySimpleGUI module being processed is { sg } ' ) ] ,
[
2020-05-16 01:15:57 +00:00
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 ' )
2020-06-28 13:59:09 +00:00
, sg . B ( ' open call ref ' , key = ' -open_call_ref- ' )
, sg . B ( ' open readme.txt ' , key = ' -open_readme.txt- ' )
, sg . B ( ' open " db folder " ' , key = ' -open_db_folder- ' )
, sg . T ( ' ' * 30 )
, sg . Col ( [
# [sg.T('output name for call_ref markdown file', key=(15,1)), sg.I(key='')],
[ * md2psg ( ' markdown outputFileName *FOR* **readme **: ' ) , sg . I ( README_OFILENAME , key = ' md1 ' ) , sg . B ( ' open in explorer ' , key = ' open in explorer_readme ' ) ] ,
[ * md2psg ( ' markdown outputFileName *FOR* **call ref**: ' ) , sg . I ( CALL_REFERENCE_OFILENAME , key = ' md2 ' ) , sg . B ( ' open in explorer ' , key = ' open in explorer_calref ' ) ]
] )
2020-05-16 01:15:57 +00:00
]
, * layout
] , resizable = True , finalize = True , location = ( 0 , 0 ) , return_keyboard_events = True )
2020-06-28 13:59:09 +00:00
def update_time_in_GUI ( ) : window [ ' -compile-time- ' ] ( datetime . datetime . today ( ) . strftime ( ' % Y- % m- %d % H: % M: % S. %f ' ) )
2020-05-16 01:15:57 +00:00
def update_compilation_in_psg ( values ) :
# get results
2020-06-28 13:59:09 +00:00
result_readme , result_call_ref = compile_all_stuff ( use_psg_color = values [ ' use_psg_color ' ] , show_time = values [ ' show_time ' ] )
# DO 2_readme
window [ ' -README-error- ' ] ( ' \n ' . join ( result_readme [ 0 ] ) )
window [ ' -README-warning- ' ] ( ' \n ' . join ( result_readme [ 1 ] ) )
window [ ' -README-info- ' ] ( ' \n ' . join ( result_readme [ 2 ] ) )
window [ ' -README-debug- ' ] ( ' \n ' . join ( result_readme [ 3 ] ) )
# /// colors warning_info
window [ ' -README-warning_info- ' ] . update ( ' ' )
2020-05-16 01:15:57 +00:00
if values [ ' use_psg_color ' ] :
2020-06-28 13:59:09 +00:00
for text , color in result_readme [ - 1 ] :
window [ ' -README-warning_info- ' ] . print ( text , text_color = color )
2020-05-16 01:15:57 +00:00
else :
2020-06-28 13:59:09 +00:00
window [ ' -README-warning_info- ' ] ( ' \n ' . join ( result_readme [ - 1 ] ) )
# DO 5_cal_ref
window [ ' -CALL_REF-error- ' ] ( ' \n ' . join ( result_call_ref [ 0 ] ) )
window [ ' -CALL_REF-warning- ' ] ( ' \n ' . join ( result_call_ref [ 1 ] ) )
window [ ' -CALL_REF-info- ' ] ( ' \n ' . join ( result_call_ref [ 2 ] ) )
window [ ' -CALL_REF-debug- ' ] ( ' \n ' . join ( result_call_ref [ 3 ] ) )
# /// colors warning_info
window [ ' -CALL_REF-warning_info- ' ] . update ( ' ' )
if values [ ' use_psg_color ' ] :
for text , color in result_call_ref [ - 1 ] :
window [ ' -CALL_REF-warning_info- ' ] . print ( text , text_color = color )
else :
window [ ' -CALL_REF-warning_info- ' ] ( ' \n ' . join ( result_call_ref [ - 1 ] ) )
# ~~~~~~~~~~~~
# GUI updating
# ~~~~~~~~~~~~
update_time_in_GUI ( )
2020-05-16 01:15:57 +00:00
update_compilation_in_psg ( { ' use_psg_color ' : not False , ' show_time ' : False } )
while True :
event , values = window ( )
2020-06-28 13:59:09 +00:00
# print(values)
if event in ( ' Exit ' , None ) :
APP_CONFIGS [ ' README_FILENAME ' ] , APP_CONFIGS [ ' CALL_REFERENCE_FILENAME ' ] = window [ ' md1 ' ] . get ( ) , window [ ' md2 ' ] . get ( )
save_configs ( APP_CONFIGS )
break
print ( ' PSG event> ' , event )
# buttons
if event == ' -run- ' : update_compilation_in_psg ( values )
if event == ' -open_readme.txt- ' : openfile ( README_OFILENAME )
if event == ' -open_call_ref- ' : openfile ( CALL_REFERENCE_OFILENAME )
if event == ' -open_db_folder- ' : opendir ( cd )
if event == ' -open_github_gallery- ' : opendir ( cd )
if event == ' open in explorer_readme ' : opendir ( os . path . dirname ( os . path . join ( cd , values [ ' md1 ' ] ) ) )
if event == ' open in explorer_calref ' : opendir ( os . path . dirname ( os . path . join ( cd , values [ ' md2 ' ] ) ) )
# hotkeys
if ' F1 ' in event : update_compilation_in_psg ( values )
2020-05-16 01:15:57 +00:00
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 ( )
2020-06-28 13:59:09 +00:00
if __name__ == ' __main__ ' :
2020-05-16 01:15:57 +00:00
mini_GUI ( )
2020-06-28 13:59:09 +00:00
# sg.PopupScrolled('Completed making {}'.format(README_OFILENAME), ''.join(lines), size=(80,50))