Skip to content

Commit d403273

Browse files
committed
Fresh commit
1 parent 1cd2183 commit d403273

15 files changed

+1314
-761
lines changed

BootstrapStudioToDjango.wpr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ proj.directory-list = [{'dirloc': loc('.'),
1212
'watch_for_changes': True}]
1313
proj.file-type = 'shared'
1414
proj.launch-config = {loc('bss_to_django.py'): ('project',
15-
('../DiagramChaseDatabase/BSSExport',
15+
('../DiagramChaseDatabase/BSSToDjango/BSSExport',
1616
'')),
1717
loc('converter.py'): ('project',
1818
('../DiagramChaseDatabase/BSSExport',
1919
'')),
2020
loc('dev_bss_to_django.py'): ('project',
2121
('BSSExport',
2222
''))}
23-
proj.main-file = loc('bss_to_django.py')
23+
proj.main-file = loc('twin_primes2.py')

BootstrapStudioToDjango.wpu

Lines changed: 521 additions & 412 deletions
Large diffs are not rendered by default.
Lines changed: 79 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -7,76 +7,65 @@
77
import math
88
import re
99

10-
class CodeGenerator(QObject):
10+
class CodeGenerator(QObject):
1111
status_message_signal = pyqtSignal(str)
1212

13-
def __init__(self, django_root:str, app_folder:str, indent:int, pickled=False):
13+
def __init__(self, code_gen_widget, pickled=False):
1414
super().__init__()
15-
self._djangoRoot = django_root
16-
self._indentSpaces = indent
17-
self._appFolder = app_folder
15+
16+
self._codeGenWidget = code_gen_widget
1817

1918
if not pickled:
2019
self._djangoTree = {}
2120
self.finish_setup()
2221

2322
def __setstate__(self, data):
24-
self.__init__(data['django root'], data['app folder'], data['indent'], pickled=True)
23+
self.__init__(data['code gen widget'], pickled=True)
2524
self._djangoTree = data['django tree']
2625
self.finish_setup()
2726

2827
def __getstate__(self):
2928
return {
3029
'django tree' : self._djangoTree,
31-
'django root' : self._djangoRoot,
32-
'indent' : self._indentSpaces,
33-
'app folder' : self._appFolder,
30+
'django root' : self.code_generation_widget,
31+
'code gen widget' : self.code_generation_widget,
3432
}
3533

3634
def finish_setup(self):
3735
pass
3836

37+
@property
38+
def code_generation_widget(self):
39+
return self._codeGenWidget
40+
3941
@property
4042
def django_project_tree(self):
4143
return self._djangoTree
4244

4345
@property
4446
def django_project_root(self):
45-
return self._djangoRoot
47+
return self.code_generation_widget.django_project_root
4648

4749
@property
4850
def num_indent_spaces(self):
49-
return self._indentSpaces
51+
return self.code_generation_widget.indent_spaces_setting
5052

5153
@property
52-
def app_folder(self):
53-
return self._appFolder
54+
def input_file(self):
55+
return self.code_generation_widget.input_file
5456

5557
def list_files_matching(self, path_pattern:str, recurse:bool=False):
5658
files = glob(path_pattern, recurse)
5759
return files
58-
59-
def output_view_code(self, function, name=None):
60-
module_path, module, attribs = self.get_module_attributes(self.django_project_root, self.app_folder, 'views.py')
61-
62-
if (name and name not in attribs) or function.__name__ not in attribs:
63-
if callable(function):
64-
source = inspect.getsource(function)
65-
else:
66-
source = str(function)
67-
68-
source = f'\n{source}'
69-
70-
with open(module_path, 'a') as module_file:
71-
module_file.write(source)
72-
60+
7361
def load_module_with_path(self, module_path:str):
7462
parts = os.path.normpath(module_path)
7563
parts = parts.split(os.sep)
7664
module_name = parts[-1]
7765
module_name,_ = os.path.splitext(module_name)
7866
module_spec = importlib.util.spec_from_file_location(module_name, location=module_path)
79-
module = importlib.util.module_from_spec(module_spec)
67+
module = importlib.util.module_from_spec(module_spec)
68+
module_spec.loader.exec_module(module)
8069
return module
8170

8271
def tabify_code(self, code:str):
@@ -110,33 +99,14 @@ def tabify_code(self, code:str):
11099

111100
return "\n".join(tabified)
112101

113-
def get_module_attributes(self, *args):
114-
module_path = os.path.join(*args)
115-
module = self.load_module_with_path(module_path)
116-
attribs = set(dir(module))
117-
return module_path, module, attribs
118-
119-
def delete_view_code_if_unmodified(self, function):
120-
module_path, module, attribs = self.get_module_attributes(self.django_project_root, self.app_folder, 'views.py')
121-
122-
if callable(function):
123-
func_name = function.__name__
124-
else:
125-
func_name = str(function)
126-
127-
if func_name in attribs:
128-
existing = getattr(module, func_name)
129-
130-
source = inspect.getsource(function)
131-
existing_source = inspect.getsource(existing)
132-
133-
if source == existing_source:
134-
with open(module_path, 'rw') as module_file:
135-
module_str = module_file.read()
136-
module_str = module_str.replace(source, '')
137-
module_file.write(module_str)
138-
else:
139-
self.status_message_signal.emit(f"{func_name} code has been modified in {module_path}, so we won't delete it.")
102+
def module_attributes(self, *args):
103+
try:
104+
module_path = os.path.join(*args)
105+
module = self.load_module_with_path(module_path)
106+
attribs = dir(module)
107+
return module_path, module, attribs
108+
except:
109+
return None, None, []
140110

141111
func_def_name_regex = re.compile(r"(?P<prefix>.*def\s+)(?P<name>[a-zA-Z_][a-zA-Z_0-9]*)(?P<suffix>\s*\(.*\)\s*:.*)", flags=re.DOTALL)
142112
def function_def_renamed(self, code_str:str, new_name:str):
@@ -147,19 +117,61 @@ def function_def_renamed(self, code_str:str, new_name:str):
147117
suffix = match.group('suffix')
148118
if name != new_name:
149119
return f'{prefix}{new_name}{suffix}'
120+
121+
@property
122+
def export_mapper(self):
123+
return self._codeGenWidget.export_mapper
124+
125+
def app_folder(self, absolute=False):
126+
django_file = self.export_mapper.django_output_file_mapping(self.input_file)
127+
django_file = self.export_mapper.filename_rel_root(django_file, root=self.export_mapper.django_project_root)
128+
129+
parts = django_file.split(os.sep)
130+
131+
if parts:
132+
if parts[0] == 'templates':
133+
return self.django_settings_folder(absolute)
134+
else:
135+
if absolute == False:
136+
return parts[0]
137+
return os.path.join(self.export_mapper.django_project_root, parts[0])
150138

151-
def rename_view_code(self, old_name:str, new_name:str):
152-
module_path, module, attribs = self.get_module_attributes(self.django_project_root, self.app_folder, 'views.py')
153-
154-
if old_name in attribs:
155-
function = getattr(module, old_name)
156-
old_source = inspect.getsource(function)
157-
new_source = self.function_def_renamed(old_source, new_name)
139+
def django_settings_folder(self, absolute=False):
140+
django_root = self.export_mapper.django_project_root
141+
142+
for folder in os.listdir(django_root):
143+
filename = os.path.join(django_root, folder)
158144

159-
with open(module_path, 'rw') as module_file:
160-
string = module_file.read()
161-
string = string.replace(old_source, new_source)
162-
module_file.write(string)
145+
if os.path.isdir(filename):
146+
for file in os.listdir(filename):
147+
if file == 'settings.py':
148+
if absolute == False:
149+
return folder
150+
return filename
151+
152+
def jump_to_code_by_boilerplate(self, boiler_plate:str):
153+
raise NotImplementedError
154+
155+
def _jump_to_code_by_boilerplate(self, boiler_plate:str):
156+
raise NotImplementedError
157+
158+
def jump_to_code(self):
159+
pass
160+
161+
@property
162+
def type_name(self):
163+
return self.__class__.__name__[:-len('Generator')]
164+
165+
def get_boilerplate_attributes(self, base_file:str):
166+
return self.module_attributes(self.django_project_root, self.export_mapper.bss_to_django_folder, self.export_mapper.boilerplates_folder, base_file)
167+
168+
@property
169+
def django_project_root(self):
170+
return self.export_mapper.django_project_root
171+
172+
def list_boilerplates(self):
173+
raise NotImplementedError
174+
163175

164176
if __name__ == '__main__':
165177
from PyQt5.QtWidgets import QApplication

code_gen/view_generator.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
from code_gen.code_generator import CodeGenerator
2+
import inspect
3+
4+
5+
class ViewGenerator(CodeGenerator):
6+
def __init__(self, code_gen_widget, pickled=False):
7+
super().__init__(code_gen_widget, pickled)
8+
9+
if not pickled:
10+
self._viewName = None
11+
self._templatePath = None
12+
self.finish_setup()
13+
14+
def __setstate__(self, data):
15+
super().__setstate__(data)
16+
self._viewName = data['view name']
17+
self._templatePath = data['template path']
18+
19+
def __getstate__(self):
20+
data = super().__getstate__()
21+
data['view name'] = self._viewName
22+
data['template path'] = self._templatePath
23+
return data
24+
25+
@property
26+
def template_path(self):
27+
return self._templatePath
28+
29+
@property
30+
def view_name(self) -> str:
31+
return self._viewName
32+
33+
def set_view_name(self, name:str):
34+
if self._viewName != name:
35+
self.rename_view_code(self.view_name, new_name=name)
36+
self._viewName = name
37+
38+
def set_template_path(self, path:str):
39+
if self._templatePath != path:
40+
# TODO
41+
self._templatePath = path
42+
43+
def output_view_code(self, function=None):
44+
if function is None:
45+
function = boilerplate_view_function
46+
view_name = self.view_name
47+
source = inspect.getsource(function)
48+
source = source.format(template_path=f'"{self.template_path}"')
49+
source = self.function_def_renamed(source, view_name)
50+
super().output_view_code(function=source, name=view_name)
51+
52+
def list_boilerplates(self) -> list:
53+
_, module, attributes = self.get_boilerplate_attributes('views.py')
54+
boilerplates = []
55+
56+
for name in attributes:
57+
attrib = getattr(module, name)
58+
59+
if callable(attrib):
60+
args = inspect.getargspec(attrib).args
61+
if args and args[0] == 'request':
62+
boilerplates.append(name)
63+
64+
return boilerplates
65+
66+
def rename_view_code(self, old_name:str, new_name:str):
67+
module_path, module, attribs = self.module_attributes(self.django_project_root, self.app_folder, 'views.py')
68+
69+
if old_name in attribs:
70+
function = getattr(module, old_name)
71+
old_source = inspect.getsource(function)
72+
new_source = self.function_def_renamed(old_source, new_name)
73+
74+
with open(module_path, 'rw') as module_file:
75+
string = module_file.read()
76+
string = string.replace(old_source, new_source)
77+
module_file.write(string)
78+
79+
def delete_view_code_if_unmodified(self, function):
80+
module_path, module, attribs = self.module_attributes(self.django_project_root, self.app_folder, 'views.py')
81+
82+
if callable(function):
83+
func_name = function.__name__
84+
else:
85+
func_name = str(function)
86+
87+
if func_name in attribs:
88+
existing = getattr(module, func_name)
89+
90+
source = inspect.getsource(function)
91+
existing_source = inspect.getsource(existing)
92+
93+
if source == existing_source:
94+
with open(module_path, 'rw') as module_file:
95+
module_str = module_file.read()
96+
module_str = module_str.replace(source, '')
97+
module_file.write(module_str)
98+
else:
99+
self.status_message_signal.emit(f"{func_name} code has been modified in {module_path}, so we won't delete it.")
100+
101+
def output_view_code(self, function, name=None):
102+
module_path, module, attribs = self.module_attributes(self.django_project_root, self.app_folder, 'views.py')
103+
104+
if (name and name not in attribs) or function.__name__ not in attribs:
105+
if callable(function):
106+
source = inspect.getsource(function)
107+
else:
108+
source = str(function)
109+
110+
source = f'\n{source}'
111+
112+
with open(module_path, 'a') as module_file:
113+
module_file.write(source)

0 commit comments

Comments
 (0)