1
- import os
2
1
import shutil
3
2
from pathlib import Path
4
- from subprocess import check_output
5
3
6
4
import streamlit as st
7
5
from codegen import CodeGenerator
10
8
__version__ = "0.1.0"
11
9
12
10
11
+ FOLDER_TO_TEMPLATE_NAME = {
12
+ "Single Model, Single Optimizer" : "single" ,
13
+ "Generative Adversarial Network" : "gan" ,
14
+ "Image Classification" : "image_classification" ,
15
+ }
16
+
17
+ TIP = """
18
+ > **💡 TIP**
19
+ >
20
+ > To quickly adapt to the generated code structure, there are TODOs in the files that are needed to be edited.
21
+ > [PyCharm TODO comments](https://www.jetbrains.com/help/pycharm/using-todo.html) or
22
+ > [VSCode Todo Tree](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree)
23
+ > can help you find them easily.
24
+ """
25
+
26
+
13
27
class App :
14
28
page_title = "Code Generator"
15
29
page_icon = "https://raw.githubusercontent.com/pytorch/ignite/master/assets/logo/ignite_logomark.svg"
@@ -39,18 +53,19 @@ def sidebar(self, template_list=None, config=None):
39
53
template_list = template_list or []
40
54
st .markdown ("### Choose a Template" )
41
55
self .template_name = st .selectbox ("Available Templates are:" , options = template_list )
56
+ self .template_name = FOLDER_TO_TEMPLATE_NAME [self .template_name ]
42
57
with st .sidebar :
43
58
if self .template_name :
44
59
config = config (self .template_name )
45
60
self .config = config .get_configs ()
46
61
else :
47
62
self .config = {}
48
63
49
- def render_code (self , fname = "" , code = "" ):
64
+ def render_code (self , fname : str = "" , code : str = "" ):
50
65
"""Main content with the code."""
51
- with st .beta_expander (f"View rendered { fname } " ):
66
+ with st .beta_expander (f"View rendered { fname } " , expanded = fname . endswith ( ".md" ) ):
52
67
if fname .endswith (".md" ):
53
- st .markdown (code )
68
+ st .markdown (code , unsafe_allow_html = True )
54
69
else :
55
70
col1 , col2 = st .beta_columns ([1 , 20 ])
56
71
with col1 :
@@ -59,22 +74,57 @@ def render_code(self, fname="", code=""):
59
74
st .code (code )
60
75
61
76
def render_directory (self , dir ):
62
- output = check_output (["tree" , dir ], encoding = "utf-8" )
77
+ """tree command is not available in all systems."""
78
+ output = f"{ dir } \n "
79
+ # https://stackoverflow.com/questions/9727673/list-directory-tree-structure-in-python
80
+ # prefix components:
81
+ space = " "
82
+ branch = "│ "
83
+ # pointers:
84
+ tee = "├── "
85
+ last = "└── "
86
+ file_count = 0
87
+ dir_count = 0
88
+
89
+ def tree (dir_path : Path , prefix : str = "" ):
90
+ """A recursive generator, given a directory Path object
91
+ will yield a visual tree structure line by line
92
+ with each line prefixed by the same characters
93
+ """
94
+ nonlocal file_count
95
+ nonlocal dir_count
96
+ contents = sorted (dir_path .iterdir ())
97
+ # contents each get pointers that are ├── with a final └── :
98
+ pointers = [tee ] * (len (contents ) - 1 ) + [last ]
99
+ for pointer , path in zip (pointers , contents ):
100
+ if path .is_file ():
101
+ file_count += 1
102
+ yield prefix + pointer + path .name
103
+ if path .is_dir (): # extend the prefix and recurse:
104
+ dir_count += 1
105
+ extension = branch if pointer == tee else space
106
+ # i.e. space because last, └── , above so no more |
107
+ yield from tree (path , prefix = prefix + extension )
108
+
109
+ for line in tree (dir ):
110
+ output += line + "\n "
111
+ output += f"\n { dir_count } directories, { file_count } files"
63
112
st .markdown ("Generated files and directory structure" )
64
113
st .code (output )
65
114
66
115
def add_sidebar (self ):
67
116
def config (template_name ):
68
117
return import_from_file ("template_config" , f"./templates/{ template_name } /_sidebar.py" )
69
118
70
- self .sidebar (self . codegen . template_list , config )
119
+ self .sidebar ([ * FOLDER_TO_TEMPLATE_NAME ] , config )
71
120
72
121
def add_content (self ):
73
122
"""Get generated/rendered code from the codegen."""
74
123
content = [* self .codegen .render_templates (self .template_name , self .config )]
75
- if st .checkbox ("View rendered code ?" ):
124
+ if st .checkbox ("View rendered code ?" , value = True ):
76
125
for fname , code in content :
77
- self .render_code (fname , code )
126
+ if len (code ): # don't show files which don't have content in them
127
+ self .render_code (fname , code )
78
128
79
129
def add_download (self ):
80
130
st .markdown ("" )
@@ -94,12 +144,13 @@ def add_download(self):
94
144
shutil .copy (archive_fname , dist_path )
95
145
st .success (f"Download link : [{ archive_fname } ](./static/{ archive_fname } )" )
96
146
with col2 :
97
- self .render_directory (os . path . join (self .codegen .dist_dir , self .template_name ))
147
+ self .render_directory (Path (self .codegen .dist_dir , self .template_name ))
98
148
99
149
def run (self ):
100
150
self .add_sidebar ()
101
151
self .add_content ()
102
152
self .add_download ()
153
+ st .info (TIP )
103
154
104
155
105
156
def main ():
0 commit comments