diff --git a/README.md b/README.md index 3786ee2..d76a6c0 100644 --- a/README.md +++ b/README.md @@ -7,5 +7,4 @@ In the final version, you will just have to execute the nassi.exe and choose you Using: Python 3.9.1 with -PySimpleGUI & -Pillow +PySimpleGUI, Pillow, Flask & wtforms diff --git a/draw/code_to_image.py b/draw/code_to_image.py index ffde39e..04bd712 100644 --- a/draw/code_to_image.py +++ b/draw/code_to_image.py @@ -6,7 +6,10 @@ datei_endung = ".png" img = None output_img = None -_bkp_font = ImageFont.truetype("res/fonts/NotoSans-Regular.ttf", 12) #in case set_font does funky stuff, backup the original font + +_bkp_font = ImageFont.load_default() + + #in case set_font does funky stuff, backup the original font font = _bkp_font @@ -77,7 +80,7 @@ def draw_if_statement(condition: str, x: int, y: int, true_sz: int, false_sz: in return x, y + text_y_size, true_sz, ysize - text_y_size, x + true_sz, y + text_y_size, false_sz, ysize - text_y_size def draw_while_loop_front(condition: str, x: int, y: int, xsize: int, ysize: int): - + if not output_img: raise Exception("Output image was not initialized! Make sure to call NSD_init first") @@ -98,7 +101,7 @@ def draw_while_loop_front(condition: str, x: int, y: int, xsize: int, ysize: int return x + xsize * .1, y + text_y_sz, xsize * .9 def draw_while_loop_back(condition: str, x: int, y: int, xsize: int, ysize: int): - + if not output_img: raise Exception("Output image was not initialized! Make sure to call NSD_init first") diff --git a/interpreter/NassiShneidermann.py b/interpreter/NassiShneidermann.py index fdb51de..2bfa914 100644 --- a/interpreter/NassiShneidermann.py +++ b/interpreter/NassiShneidermann.py @@ -62,9 +62,9 @@ class NassiShneidermanDiagram: number_of_item = 1 for scope in self.function_scopes: number_of_item += 1 - cancel = one_line_progress_meter('Progress', number_of_item, len(self.function_scopes), '-PROGRESSBAR-') - if not cancel: - return False + # cancel = one_line_progress_meter('Progress', number_of_item, len(self.function_scopes), '-PROGRESSBAR-') + # if not cancel: + # return False filepath = f"{output_path}/{scope.name}" filepath = self.check_conflicts(filepath, on_conflict) diff --git a/interpreter/interpret_source.py b/interpreter/interpret_source.py index f419c17..876d159 100644 --- a/interpreter/interpret_source.py +++ b/interpreter/interpret_source.py @@ -118,7 +118,7 @@ class JavaInterpreter: def _get_scope_start_offset(self, i: int) -> int: if self._check_src(i, "{"): return 1 - elif self._check_src(i+1, "{"): + elif self._check_src(i+1, "{"): return 2 raise ScopeNotFoundException("Unable to find scope start. Is the program ill-formed?") @@ -128,7 +128,7 @@ class JavaInterpreter: instruction_txt = line[6:bracket_idx] child_instructions, idx = self._get_subscope(idx) return while_instruction_front(("while" + instruction_txt), child_instructions), idx - + def _get_subscope(self, idx: int): brace_offset = self._get_scope_start_offset(idx) return self._get_instructions_in_scope(idx+brace_offset) @@ -144,7 +144,7 @@ class JavaInterpreter: else: logging.debug("found else construct in line: %i", idx+1) instructions, idx = self._get_subscope(idx) - + elif self._check_line_start(idx+1, "else"): if self._check_src(idx+1, "if("): logging.debug("found else if construct in line: %i", idx+2) @@ -155,7 +155,7 @@ class JavaInterpreter: logging.debug("found else construct in line: %i", idx+2) instructions, idx = self._get_subscope(idx+1) return instructions, idx - + def _handle_if(self, line: str, idx: int): bracket_idx = line.rindex(')') # throws if the contruct is illformed @@ -164,7 +164,7 @@ class JavaInterpreter: true_instructions, idx = self._get_subscope(idx) false_instructions, idx = self._get_else_scope(idx) - + return if_instruction(instruction_txt, true_instructions, false_instructions), idx def _handle_do_while(self, line: str, idx: int): @@ -193,7 +193,7 @@ class JavaInterpreter: var = segments[0][4:] cond = segments[1] inc = segments[2][:-2] - + instructions = [] if cond == "": #did you know test expressions where optional and defaulted to true? Me neither @@ -202,16 +202,16 @@ class JavaInterpreter: if var != "": variable_instruction = self._handle_variable(var, idx)[0] instructions.append(variable_instruction) - + brace_offset = self._get_scope_start_offset(idx) child_instructions, idx = self._get_instructions_in_scope(idx+brace_offset) - + if inc != "": increment_instruction = generic_instruction(inc) child_instructions.append(increment_instruction) instructions.append(for_instruction("while " + cond, child_instructions)) - + return instructions, idx except IndexError: @@ -232,7 +232,7 @@ class JavaInterpreter: if line.startswith("while("): logging.debug("Found while construct in line: %i", idx+1) return self._handle_while(line, idx) - + elif line.startswith("if("): logging.debug("Found if construct in line: %i", idx+1) return self._handle_if(line, idx) @@ -258,7 +258,7 @@ class JavaInterpreter: i = idx while i < len(self._lines): line = self._lines[i] - + if self._check_src(i, '}'): break @@ -270,7 +270,7 @@ class JavaInterpreter: i += 1 return scope, i - + def _remove_keywords(self): self.src = self._src.replace(' ', '') self.src = self._comment_pattern.sub('', self.src) diff --git a/run.py b/run.py index 4e70a49..95a5aa3 100755 --- a/run.py +++ b/run.py @@ -4,4 +4,7 @@ import sys do_debug = "--debug" in sys.argv -Gui(theme='DarkGrey11', debug_mode=do_debug) \ No newline at end of file +Gui(theme='DarkGrey11', debug_mode=do_debug) + + + diff --git a/run_web.py b/run_web.py new file mode 100644 index 0000000..06761d8 --- /dev/null +++ b/run_web.py @@ -0,0 +1,7 @@ +from web_app import create_app + + +app = create_app() + +if __name__ == '__main__': + app.run(port=7467 ,debug=False) \ No newline at end of file diff --git a/tmp/output.zip b/tmp/output.zip new file mode 100644 index 0000000..c669cca Binary files /dev/null and b/tmp/output.zip differ diff --git a/tmp/output/56.zip b/tmp/output/56.zip new file mode 100644 index 0000000..c1b4f1e Binary files /dev/null and b/tmp/output/56.zip differ diff --git a/web_app/__init__.py b/web_app/__init__.py new file mode 100644 index 0000000..fe7fbaf --- /dev/null +++ b/web_app/__init__.py @@ -0,0 +1,15 @@ +from flask import Flask +from web_app.config import Config + +app = Flask(__name__) + +def create_app(config_class=Config): + app.config.from_object(config_class) + + from web_app.main.routes import main + from web_app.errors.handlers import errors + + app.register_blueprint(main) + app.register_blueprint(errors) + + return app \ No newline at end of file diff --git a/web_app/config.py b/web_app/config.py new file mode 100644 index 0000000..095d79d --- /dev/null +++ b/web_app/config.py @@ -0,0 +1,2 @@ +class Config(): + SECRET_KEY = '4542bae72a9fefada779b8c3fc68a826' diff --git a/web_app/errors/__init__.py b/web_app/errors/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web_app/errors/handlers.py b/web_app/errors/handlers.py new file mode 100644 index 0000000..b79f13d --- /dev/null +++ b/web_app/errors/handlers.py @@ -0,0 +1,23 @@ +from flask import Blueprint, render_template + +errors = Blueprint('errors', __name__) + +@errors.app_errorhandler(404) +def error_404(error): + return render_template('errors/404.html'), 404 + +@errors.app_errorhandler(403) +def error_403(error): + return render_template('errors/403.html'), 403 + +@errors.app_errorhandler(500) +def error_500(error): + return render_template('errors/500.html'), 500 + +@errors.app_errorhandler(418) +def error_600(error): + return render_template('errors/418.html'), 418 + +@errors.app_errorhandler(501) +def error_600(error): + return render_template('errors/512.html'), 501 \ No newline at end of file diff --git a/web_app/main/__init__.py b/web_app/main/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web_app/main/forms.py b/web_app/main/forms.py new file mode 100644 index 0000000..fb64dfc --- /dev/null +++ b/web_app/main/forms.py @@ -0,0 +1,12 @@ +from flask_wtf import FlaskForm +from wtforms import FileField, SubmitField +from wtforms.validators import Optional +from flask_wtf.file import FileAllowed +from wtforms.fields.core import StringField + +class UploadJavaForm(FlaskForm): + comments = StringField('Enter customn comments (//, #, ...): ', validators=(Optional())) + types = StringField('custom types (//, #, ...)', validators=(Optional())) + remove_tags = StringField('Enter customn modifier (public, private, ...): ', validators=(Optional())) + java = FileField('.java hochladen', validators=[FileAllowed(['java', 'txt'])]) + submit = SubmitField('Bestätigen') \ No newline at end of file diff --git a/web_app/main/routes.py b/web_app/main/routes.py new file mode 100644 index 0000000..a2f4cc1 --- /dev/null +++ b/web_app/main/routes.py @@ -0,0 +1,86 @@ +from flask.helpers import send_file +from flask import render_template, abort, flash, Blueprint +from web_app.main.forms import UploadJavaForm +from random import randint +import shutil +import secrets +import os +import logging + +from gui.utils import nassi +from interpreter.NassiShneidermann import NassiShneidermanDiagram, OB + +main = Blueprint('main', __name__) + +def deleteFilesInFolder(path): + file_list = os.listdir(path) + for f in file_list: + try: + os.remove(path + '/' +f) + # print("remove " + f) + except: + try: + shutil.rmtree(path + '/' + f) + # print("remove " + f) + except: + logging.error("fail to remove " + f) + + +def javaDatei(form_file): + try: + random_hex = secrets.token_hex(8) + _, f_ext = os.path.splitext(form_file.filename) + file_fname = random_hex + f_ext + dirctory_path = os.path.abspath(os.path.join('Web', os.pardir)) + file_path = os.path.join(dirctory_path, './tmp/input', file_fname) + form_file.save(file_path) + return file_path + except: + flash('Hier ist was falsch gelaufen!') + + +@main.route('/', methods=['POST', 'GET']) +@main.route('/generator', methods=['POST','GET']) +def generator(): + form = UploadJavaForm() + + if form.validate_on_submit(): + if form.java.data: + input_path = javaDatei(form.java.data) + output_path = os.path.join(os.path.abspath(os.path.join('Web', os.pardir)), './tmp/input') + outputname = str(randint(0, 100) ) + output_path_zip = os.path.join(os.path.abspath(os.path.join('Web', os.pardir)), f'./tmp/output/{outputname}') + + behaviour = OB.RANDOM_NAME + + + + deleteFilesInFolder(str(os.path.join(os.path.abspath(os.path.join('Web', os.pardir)), './tmp/output/'))) + NSD = NassiShneidermanDiagram(True) + output_directory = output_path + '/' + outputname + + + try: + if not os.path.exists(output_directory): + os.makedirs(output_directory) + except OSError: + logging.error('Error: Creating directory. ' + output_directory) + + + custom_tags = {"comments" : form.comments.data, "ignore" : form.remove_tags.data, "types" : form.types.data} + + NSD.load_from_file(input_path, custom_tags) + NSD.convert_to_image(output_directory, on_conflict=behaviour) + + shutil.make_archive(output_path_zip, 'zip', output_directory) + + deleteFilesInFolder(output_path) + return send_file(output_path_zip + '.zip', as_attachment=True) + + + + return render_template('upload.html', title='Upload', legend='Upload', form=form ) + +@main.route('/working', methods=['POST', 'GET']) +def working(): + abort(501) \ No newline at end of file diff --git a/web_app/static/main.css b/web_app/static/main.css new file mode 100644 index 0000000..deb1063 --- /dev/null +++ b/web_app/static/main.css @@ -0,0 +1,90 @@ + +body { +color: #ffffff; +margin-top: 5rem; +} + +h1, h2, h3, h4, h5, h6 { +color: #ffffff; +} + +.black-text { + color: #000000; +} + +.bg-steel { +background-color: #49484d; +} + +.site-header .navbar-nav .nav-link { +color: #cbd5db; +} + +.site-header .navbar-nav .nav-link:hover { +color: #ffffff; +} + +.site-header .navbar-nav .nav-link.active { +font-weight: 500; +} + +.content-section { +background: #444444; +padding: 10px 20px; +border: 10px solid #444455; +border-style: groove; +border-radius: 30px 1px 30px 1px; +margin-bottom: 20px; +} + +.article-title { +color: #ffffff; +} + +a.article-title:hover { +color: #428bca; +text-decoration: none; +} + +.article-content { +white-space: pre-line; +color: aliceblue; +} + +.article-img { +height: 65px; +width: 65px; +margin-right: 16px; +} + +.article-metadata { +padding-bottom: 1px; +margin-bottom: 4px; +border-bottom: 1px solid #ffffff +} + +.article-metadata a:hover { +color: #ffffff; +text-decoration: none; +} + +.article-svg { +width: 25px; +height: 25px; +vertical-align: middle; +} + +.account-img { +height: 125px; +width: 125px; +margin-right: 20px; +margin-bottom: 16px; +} + +.account-heading { +font-size: 2.5rem; +} + +.label-filter { + color: #291852; +} diff --git a/web_app/templates/datenschutz.html b/web_app/templates/datenschutz.html new file mode 100644 index 0000000..90e7fb4 --- /dev/null +++ b/web_app/templates/datenschutz.html @@ -0,0 +1,7 @@ +{% extends 'layout.html' %} +{% block content %} +
+Falls dies nicht der Fall ist, hier die Zieladresse https://ole-siepmann.de/startseite/datenschutzerklaerung/ an die Sie weitergeleitet werden.
+{% endblock content %} \ No newline at end of file diff --git a/web_app/templates/errors/403.html b/web_app/templates/errors/403.html new file mode 100644 index 0000000..b87049e --- /dev/null +++ b/web_app/templates/errors/403.html @@ -0,0 +1,7 @@ +{% extends 'layout.html' %} +{% block content %} +Hier gibt es nichts zusehen, suchen Sie an einem anderen Ort!
+Versuch es in Zukunft nochmal oder frag Ole, wie lange er für diese Funktion noch brauch. Wenn du einen Verbesserungsvorschlag hast, melde dich bei Ole.
+Versuch es in naher Zukunft nochmal.
+Hier gibt es nichts zusehen!
+WARNING Because the Interpreter is still WIP, some Java language features are not supported. These include: + *foreach loops (will throw JavaSyntaxError) + *constructors (will be ignored) + *switch statements + Please remove these features from the source code as they will result in incorrect behaviour
+