Merge pull request #2 from plexx-dev/0.3-A

0.3 a
This commit is contained in:
Weckyy702
2023-03-20 08:43:24 +00:00
committed by GitHub
36 changed files with 1118 additions and 947 deletions

View File

@@ -24,15 +24,9 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. MacOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
- OS: [e.g. Win10]
- Browser [e.g. chrome, safari] // Only if you use our Website
- Version [e.g. 0.2]
**Additional context**
Add any other context about the problem here.

View File

@@ -8,6 +8,20 @@ In the final version, you will just have to execute the nassi.exe and choose you
Using:
Python 3.9.1 with
<<<<<<< HEAD
PySimpleGUI, Pillow
## Run
1. ```
pip install -r requirements.txt
```
2. ```
python run.py
```
=======
PySimpleGUI, Pillow, Flask & wtforms
[Just a Visualization of our Progress](https://www.youtube.com/watch?v=WOCruSSG3qg)
>>>>>>> main

View File

@@ -1,85 +1,76 @@
from typing import Iterable, List
"""Interafce for all instruction types"""
__author__ ="Weckyy702"
from abc import ABCMeta, abstractmethod
from draw import code_to_image as cti
from typing import Tuple, List, Optional
class Iinstruction(metaclass=ABCMeta):
"""Base class for all instructions"""
from . import code_to_image as cti
class instruction(metaclass=ABCMeta):
def __init__(self, instruction_text: str) -> None:
self.instruction_text = instruction_text
@abstractmethod
def to_image(self, x:int, y:int, x_sz: int) -> Iterable[float]:
def convert_to_image(self, x: int, y: int, width: int) -> int:
pass
@abstractmethod
def getblkheight(self) -> float:
pass
def get_block_width(self):
return self.get_text_width()
@abstractmethod
def getblkwidth(self) -> float:
pass
def get_block_height(self):
return self.get_text_height()
@abstractmethod
def __str__(self) -> str:
pass
def _getblkheight(self) -> float:
def get_text_width(self):
return cti.get_text_size(self.instruction_text)[0]
def get_text_height(self):
return cti.get_text_size(self.instruction_text)[1]
def _getblkwidth(self) -> float:
return cti.get_text_size(self.instruction_text)[0]+50 #padding
class generic_instruction(Iinstruction):
"""Any instruction that is not a control structure"""
class generic_instruction(instruction):
def __init__(self, instruction_text: str) -> None:
Iinstruction.__init__(self, instruction_text)
super().__init__(instruction_text)
def to_image(self, x:int, y:int, x_sz: int) -> Iterable[float]:
return cti.draw_generic_instruction(self.instruction_text, x, y, x_sz, self.getblkheight())
def convert_to_image(self, x: int, y: int, width: int) -> int:
height = self.get_block_height()
return cti.draw_generic_instruction(self.instruction_text, x, y, width, height)
def getblkheight(self) -> float:
return self._getblkheight()
def get_block_width(self):
return super().get_block_width()
def getblkwidth(self) -> float:
return self._getblkwidth()
def get_block_height(self):
return super().get_block_height()
def __str__(self) -> str:
return self.instruction_text
class if_instruction(Iinstruction):
"""Conditional structure
NOT.
A.
LOOP
"""
def __init__(self, instruction_text: str, true_case: List[Iinstruction], false_case: List[Iinstruction]=None) -> None:
Iinstruction.__init__(self, instruction_text)
class if_instruction(instruction):
def __init__(self, instruction_text: str, true_case: List[instruction], false_case: Optional[List[instruction]]) -> None:
super().__init__(instruction_text)
self.true_case = true_case
self.false_case = false_case
def get_trueheight(self) -> float:
sz = 0.0
for inst in self.true_case:
sz += inst.getblkheight()
return sz
def convert_to_image(self, x: int, y: int, width: int) -> int:
true_width = self.get_true_width()
block_height = self.get_block_height()
def get_falseheight(self) -> float:
sz = 0.0
if self.false_case:
for inst in self.false_case:
sz += inst.getblkwidth()
return sz
true_x, true_y, false_x, false_y = cti.draw_if_statement(self.instruction_text, x, y, true_width, width, block_height)
def getblkheight(self) -> float:
return self._getblkheight() + max(self.get_trueheight(), self.get_falseheight())
self.draw_children(true_x, true_y, true_width, false_x, false_y, width-true_width)
def getblkwidth(self) -> float:
return max(self._getblkwidth(), self.get_truewidth() + self.get_falsewidth())
return y + self.get_block_height()
<<<<<<< HEAD
def draw_children(self, true_x:int, true_y:int, true_width:int, false_x:int, false_y:int, false_width:int):
=======
def get_truewidth(self) -> float:
w = 50
@@ -110,43 +101,63 @@ class if_instruction(Iinstruction):
return x, y + blk_size
def draw_true_case(self, x: float, y:float, x_sz:float):
>>>>>>> main
for instruction in self.true_case:
x, y = instruction.to_image(x, y, x_sz)
true_y = instruction.convert_to_image(true_x, true_y, true_width)
def draw_false_case(self, x: float, y:float, x_sz:float):
if self.false_case:
for instruction in self.false_case:
x, y = instruction.to_image(x, y, x_sz)
false_y = instruction.convert_to_image(false_x, false_y, false_width)
def __str__(self) -> str:
res = f"if({self.instruction_text}) {'{'}\n"
for inst in self.true_case:
res += '\t'+str(inst)+";\n"
res += "}"
def get_block_width(self) -> int:
text_width = self.get_text_width()
true_width = self.get_true_width()
false_width = self.get_false_width()
return max(text_width, true_width + false_width)
def get_block_height(self):
text_height = self.get_text_height()
true_height = self.get_true_height()
false_height = self.get_false_height()
return text_height + max(true_height, false_height)
def get_text_width(self):
return int(super().get_text_width() * 1.5)
def get_true_width(self) -> int:
width = 200
for instruction in self.true_case:
width = max(width, instruction.get_block_width())
return width
def get_false_width(self) -> int:
width = 200
if self.false_case:
res += " else {"
for inst in self.true_case:
res += '\t'+str(inst)+";\n"
res += "}"
return res
for instruction in self.false_case:
width = max(width, instruction.get_block_width())
return width
#TODO
# class switch_instruction(Iinstruction):
# """Switch structure"""
def get_true_height(self) -> int:
height = 0
# def __init__(self, instruction_text: str, cases: List[List[Iinstruction]]) -> None:
# Iinstruction.__init__(self, instruction_text)
# self.child_cases = cases
for instruction in self.true_case:
height += instruction.get_block_height()
# def to_image(self, x:int, y:int, x_sz: int, y_sz: int) -> Iterable[float]:
# """TODO: implement"""
# return []
return height
# def draw_children(self, x:float, y:float, x_sz:float, y_sz:float) -> float:
# """TODO: implement"""
# return 0.0
def get_false_height(self) -> int:
height = 0
if self.false_case:
for instruction in self.false_case:
height += instruction.get_block_height()
<<<<<<< HEAD
return height
=======
class while_instruction_front(Iinstruction):
@@ -183,30 +194,107 @@ class while_instruction_front(Iinstruction):
for inst in self.child_instructions:
x, y = inst.to_image(x, y, x_sz)
return self.get_children_height()
>>>>>>> main
def __str__(self) -> str:
res = "while(" + self.instruction_text + "){\n"
for inst in self.child_instructions:
res += '\t'+str(inst)+";\n"
res += '}'
res = "if\n"
for instruction in self.true_case:
res += '\t' + str(instruction) + '\n'
if self.false_case:
res += "else\n"
for instruction in self.false_case:
res += '\t' + str(instruction) + '\n'
return res
class while_instruction_back(while_instruction_front):
def __init__(self, condition: str, instructions: List[Iinstruction]) -> None:
while_instruction_front.__init__(self, condition, instructions)
def to_image(self, x:int, y:int, x_sz: int):
children_x, children_y, children_sz_x = cti.draw_while_loop_back(self.instruction_text, x, y, x_sz, self.getblkheight())
self.draw_children(children_x, children_y, children_sz_x)
return x, y + self.getblksize()
class while_instruction_front(instruction):
def __init__(self, condition_text: str, child_instructions: List[instruction]) -> None:
super().__init__(condition_text)
self.children = child_instructions
def convert_to_image(self, x: int, y: int, width: int) -> int:
block_height = self.get_block_height()
children_x, children_y, children_width = cti.draw_while_loop_front(self.instruction_text, x, y, width, block_height)
self.draw_children(children_x, children_y, children_width)
return y + block_height
def draw_children(self, children_x:int, children_y:int, children_width:int):
for instruction in self.children:
children_y = instruction.convert_to_image(children_x, children_y, children_width)
def get_block_width(self):
width = self.get_text_width()
for instruction in self.children:
width = max(width, instruction.get_block_width() / (1 - cti.BLOCK_OFFSET_RATIO)) #instructions inside a bock take up more space, so compensate for that
return int(width)
def get_block_height(self):
height = self.get_text_height()
for instruction in self.children:
height += instruction.get_block_height()
return height
def __str__(self) -> str:
res = "do{\n"
for inst in self.child_instructions:
res += '\t' +str(inst) + ";\n"
res += f"{'}'}while({self.instruction_text});"
res = "while\n"
for instruction in self.children:
res += '\t' + str(instruction) + '\n'
return res
class while_instruction_back(while_instruction_front):
def __init__(self, condition_text: str, child_instructions: List[instruction]) -> None:
super().__init__(condition_text, child_instructions)
def convert_to_image(self, x: int, y: int, width: int) -> int:
block_height = self.get_block_height()
children_x, children_y, children_width = cti.draw_while_loop_back(self.instruction_text, x, y, width, block_height)
self.draw_children(children_x, children_y, children_width)
return y + block_height
def __str__(self) -> str:
res = "do\n"
for instruction in self.children:
res += '\t' + str(instruction) + '\n'
res += "while"
return res
class for_instruction(while_instruction_front):
pass
def __init__(self, variable_text: str, condition_text: str, child_instruction: List[instruction]) -> None:
super().__init__(condition_text, child_instruction)
self.variable_instruction = generic_instruction(variable_text)
def convert_to_image(self, x: int, y: int, width: int) -> int:
block_height = super().get_block_height()
y = self.variable_instruction.convert_to_image(x, y, width)
children_x, children_y, children_width = cti.draw_while_loop_front(self.instruction_text, x, y, width, block_height)
self.draw_children(children_x, children_y, children_width)
return y + block_height
def get_block_width(self):
return max(super().get_block_width(), self.variable_instruction.get_block_width())
def get_block_height(self):
return super().get_block_height() + self.variable_instruction.get_block_height()
def __str__(self) -> str:
res = str(self.variable_instruction) + '\n'
res += "for\n"
for instruction in self.children:
res += "\t" + str(instruction) + '\n'
return res

View File

@@ -1,6 +1,16 @@
from typing import Iterable
"""code_to_image.py: #TODO"""
__author__ = "plexx, Weckyy702"
from typing import Tuple
from PIL import Image, ImageDraw, ImageFont
import os
import random
PADDING_X = 50
PADDING_Y = 5
BLOCK_OFFSET_RATIO = .1
datei_endung = ".png"
@@ -9,14 +19,17 @@ output_img = None
_bkp_font = ImageFont.truetype("res/fonts/NotoSans-Regular.ttf", 12) # ImageFont.load_default()
#in case set_font does funky stuff, backup the original font
ERROR_TEXT = "Output image was not initialized! Make sure to call NSD_init first"
#in case set_font does funky stuff, backup the original font
font = _bkp_font
def NSD_init(x: float, y: float):
#get input_img
global img, output_img
#img = Image.open(input_dir + file_name + datei_endung)
img = Image.new("RGB", (x, y), "white")
output_img = ImageDraw.Draw(img)
@@ -31,97 +44,111 @@ def set_font(font_filepath: str):
raise
def get_text_size(text: str):
def get_text_size(text: str) -> Tuple[int, int]:
if not font:
raise Exception("Output image was not initialized! Make sure to call NSD_init first")
return font.getsize(text)
raise Exception(ERROR_TEXT)
size = font.getsize(text)
def draw_debug_tile(x, y, x_sz, y_sz):
from random import randint
return (size[0]+PADDING_X, size[1]+PADDING_Y)
output_img.rectangle((x, y) + (x + x_sz, y + y_sz), fill=(randint(0, 255)))
return x, y + y_sz
def draw_generic_instruction(instruction: str, x, y, xsize, ysize) -> Iterable[float]:
def draw_debug_tile(x:int, y:int, width:int, height:int) -> int:
fill_color = (random.randint(0, 255),random.randint(0, 255), random.randint(0, 255))
output_img.rectangle((x,y) + (x+width, y+height), outline=(0), fill=fill_color)
return y + height
def draw_generic_instruction(instruction: str, x: int, y: int, width:int, height:int) -> int:
if not output_img:
raise Exception("Output image was not initialized! Make sure to call NSD_init first")
raise Exception(ERROR_TEXT)
#draw shit
output_img.rectangle((x,y) + (x + xsize, y + ysize), outline=(0), width=1)
output_img.rectangle((x,y) + (x + width, y + height), outline=(0), width=1)
#text shit
output_img.multiline_text((x + xsize * .5, y + ysize * .5), instruction, font=font, anchor="mm", align="right", fill=(0))
output_img.multiline_text((x + width * .5, y + height * .5), instruction, font=font, anchor="mm", align="right", fill=(0))
return x, y + ysize
return y + height
def draw_if_statement(condition: str, x: int, y: int, true_sz: int, false_sz: int, ysize: int):
def draw_if_statement(condition: str, x: int, y: int, true_width: int, block_width:int, block_height: int) -> Tuple[int, int, int, int]:
"""Draw an if statement into the NSD"""
if not output_img:
raise Exception("Output image was not initialized! Make sure to call NSD_init first")
raise Exception(ERROR_TEXT)
text_y_size = font.getsize(condition)[1]
text_height = get_text_size(condition)[1]
box_sz = true_sz + false_sz
#condition
output_img.rectangle((x, y) + (x + block_width, y + text_height), outline=(0), width=1) #Box around condition text
output_img.multiline_text((x + true_width, y + text_height / 2), condition, fill=(0), font=font, anchor="mm", spacing=4, align='right')
<<<<<<< HEAD
#fancy lines for the "true" and "false" labels
output_img.line((x,y) + (x + true_width, y + text_height), fill=(0))
output_img.line((x + block_width, y) + (x + true_width, y + text_height), fill=(0))
# "true" and "false" labels
output_img.text((x + 5, y + text_height), "true", font = font, fill = (0), anchor="ld")
output_img.text((x + block_width - 5, y + text_height), "false", font = font, fill = (0), anchor="rd")
=======
output_img.line((x,y) + (x + true_sz, y + text_y_size), fill=(0))
output_img.line((x + box_sz, y) + (x + true_sz, y + text_y_size), fill=(0))
output_img.rectangle((x, y + text_y_size) + (x + box_sz, y + ysize), outline=(0), width=1)
output_img.rectangle((x, y) + (x + box_sz, y + text_y_size), outline=(0), width=1)
output_img.line((x + true_sz, y + text_y_size) + (x + true_sz, y + ysize), fill=(0))
>>>>>>> main
# condition text
output_img.multiline_text((x + box_sz / 2, y + text_y_size / 2), condition, fill=(0), font=font, anchor="mm", spacing=4, align='right')
output_img.line((x + true_width, y + text_height) + (x + true_width, y + block_height), fill=(0))
# true / false
output_img.text((x + 5, y + text_y_size), "true", font = font, fill = (0), anchor="ld")
output_img.text((x + box_sz - 5, y + text_y_size), "false", font = font, fill = (0), anchor="rd")
#x and y of "true" and "false" label
return x, y + text_height, x + true_width, y + text_height
#first x, y, xsize and ysize of "true" label then of "false" label
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):
def draw_while_loop_front(condition: str, x: int, y: int, block_width: int, block_height: int) -> Tuple[int, int, int]:
if not output_img:
raise Exception("Output image was not initialized! Make sure to call NSD_init first")
raise Exception(ERROR_TEXT)
text_y_sz = font.getsize(condition)[1]
text_height = get_text_size(condition)[1]
block_offset = int(block_width * BLOCK_OFFSET_RATIO)
#the box
output_img.line((x,y) + (x + xsize, y), fill=(0))
output_img.line((x,y) + (x, y + ysize), fill=(0))
output_img.line((x + xsize * .1, y + text_y_sz) + (x + xsize, y + text_y_sz), fill=(0))
output_img.line((x + xsize, y) + (x + xsize, y + text_y_sz), fill=(0))
output_img.line((x, y + ysize) + (x + xsize * .1, y + ysize ), fill=(0))
output_img.line((x + xsize * .1, y + ysize) + (x + xsize * .1, y + text_y_sz), fill=(0))
output_img.line((x,y) + (x + block_width, y), fill=(0))
output_img.line((x,y) + (x, y + block_height), fill=(0))
output_img.line((x + block_offset, y + text_height) + (x + block_width, y + text_height), fill=(0))
output_img.line((x + block_width, y) + (x + block_width, y+text_height), fill=(0))
#the text
output_img.text((x + xsize * .1, y + text_y_sz * .5), condition, font = font, fill = (0), anchor="lm")
output_img.text((x + block_offset, y + text_height * .5), condition, font = font, fill = (0), anchor="lm")
#the x, y offset then the x,y draw size (the canvas)
return x + xsize * .1, y + text_y_sz, xsize * .9
#the x, y offset then the children width
return x + block_offset, y + text_height, block_width - block_offset
def draw_while_loop_back(condition: str, x: int, y: int, xsize: int, ysize: int):
def draw_while_loop_back(condition: str, x: int, y: int, block_width: int, block_height: int):
if not output_img:
raise Exception("Output image was not initialized! Make sure to call NSD_init first")
raise Exception(ERROR_TEXT)
text_y_sz = get_text_size(condition)[1]
text_height = get_text_size(condition)[1]
block_offset = int(block_width * BLOCK_OFFSET_RATIO)
#the box
output_img.line((x,y) + (x + xsize * .1, y), fill=0)
output_img.line((x + xsize * .1, y) + (x + xsize * .1, y + ysize - text_y_sz), fill=0)
output_img.line((x + xsize * .1, y + ysize - text_y_sz) + (x + xsize, y + ysize - text_y_sz), fill=0)
output_img.line((x + xsize, y + ysize - text_y_sz) + (x + xsize, y + ysize), fill=0)
output_img.line((x,y + ysize) + (x + xsize, y + ysize), fill=0)
output_img.line((x,y) + (x, y + ysize), fill=0)
output_img.line((x,y) + (x + block_offset, y), fill=0)
output_img.line((x + block_offset, y) + (x + block_offset, y + block_height - text_height), fill=0)
output_img.line((x + block_offset, y + block_height - text_height) + (x + block_width, y + block_height - text_height), fill=0)
output_img.line((x + block_width, y + block_height - text_height) + (x + block_width, y + block_height), fill=0)
output_img.line((x,y + block_height) + (x + block_width, y + block_height), fill=0)
output_img.line((x,y) + (x, y + block_height), fill=0)
#the text
output_img.text((x + xsize * .1, y + ysize - text_y_sz * .5), condition, font = font, fill = (0), anchor="lm")
output_img.multiline_text((x + block_offset, y + block_height - text_height * .5), condition, font = font, fill = (0), anchor="lm")
#the x, y offset then the x,y draw size (the canvas)
return x + xsize * .1, y, xsize * .9
#x, y and width of children
return x + block_offset, y, block_width - block_offset
def NSD_save(filepath: str):
"""Save the created file"""
filepath = filepath.removesuffix(".png")
filepath = filepath.removesuffix(datei_endung)
img.save(filepath + datei_endung ,"PNG")

View File

@@ -1,3 +1,8 @@
"""code_to_image_wrapper.py: #TODO"""
__author__ = "Weckyy702"
import draw.code_to_image as cti
class NSD_writer(object):

View File

@@ -1,4 +1,9 @@
from gui.utils import nassi, output
"""gui.py: handle and init Gui."""
__author__ = "oleting"
from gui.utils import nassi_file, filter_folder
from gui.new_window_layouts import Layout_std, Layout_settings
from errors.custom import JavaSyntaxError, ScopeNotFoundException, InterpreterException, NoPathError
from interpreter.NassiShneidermann import OB
@@ -41,9 +46,10 @@ class Gui:
def gui_handler(self, window: sg.Window):
# handler for the gui
file_path = None
font_filepath = None
output_name = None
output_path = None
exists_choice = OB.SKIP
types = None
comments = None
@@ -67,17 +73,19 @@ class Gui:
window_settings = sg.Window(title='Settings', layout=layout_settings.layout, resizable=False)
event_settings, values_settings = window_settings.read()
while event_settings != '-EXIT-':
if event_settings == '-OVERWRITE-' and exists_choice != OB.OVERWWRITE:
exists_choice = OB.OVERWWRITE
if event_settings == '-OVERWRITE-' and exists_choice != OB.OVERWRITE:
exists_choice = OB.OVERWRITE
break
if event_settings == '-EXPICIT-' and exists_choice != OB.RANDOM_NAME:
elif event_settings == '-EXPICIT-' and exists_choice != OB.RANDOM_NAME:
exists_choice = OB.RANDOM_NAME
break
if event_settings == '-SKIP-' and exists_choice != OB.SKIP:
elif event_settings == '-SKIP-' and exists_choice != OB.SKIP:
exists_choice = OB.SKIP
break
if event_settings == sg.WIN_CLOSED or event == 'Quit':
elif event_settings == sg.WIN_CLOSED or event == 'Quit':
break
else:
pass
window_settings.close()
if event == '-CREATE-':
@@ -98,15 +106,18 @@ class Gui:
'You didn\'t set a name for the image, it will be named randomly.')
output_name = secrets.token_hex(16)
path = nassi(input_path=file_path, output_path=output_path, outputname=output_name, gui=self,
path, file_is_empty = nassi_file(input_path=file_path, output_path=output_path, outputname=output_name, gui=self,
font_filepath=font_filepath, behaviour=exists_choice, types=types, remove_tags=modifier, comments=comments)
if file_is_empty:
sg.popup_annoying('Our interpreter did not find anything. --> blame Kons or yourself!', title='Empty')
if path:
fnames = output(path)
fnames = filter_folder(path)
sg.popup_annoying('Successfully created!', title='Created',
auto_close_duration=2, auto_close=True, text_color='green')
window['-OUTPUT FILE LIST-'].update(fnames)
else:
fnames = output(output_path, output_name)
fnames = filter_folder(output_path, output_name)
sg.popup_annoying('There are some images created!', title='Cancel',
auto_close_duration=2, auto_close=True, text_color='green')
window['-OUTPUT FILE LIST-'].update(fnames)
@@ -114,11 +125,11 @@ class Gui:
except JavaSyntaxError as JsE:
logging.error(
('||SyntaxError in Java File|| Failed to create Image with values = ' + str(values)))
sg.popup_error((str(JsE)))
sg.popup_error(str(JsE))
except ScopeNotFoundException as SnFe:
logging.error(
('||ScopeNotFoundExeption|| Failed to create Image with values = ' + str(values)))
sg.popup_error((str(SnFe)))
sg.popup_error(str(SnFe))
except FileNotFoundError as FnFe:
logging.error(
('||FileNotFoundError|| Failed to create Image with values = ' + str(values)))
@@ -130,7 +141,63 @@ class Gui:
except Exception as e:
logging.error(
('Failed to create Image with values = ' + str(values)))
sg.popup_error(('Failed to create an image of one funktion correctly. ' + str(e)) + 'There may be some images created. ')
sg.popup_error(('Failed to create an image of one function correctly. ' + str(e)) + 'There may be some images created. ')
except:
raise
elif values['-INPUT FOLDER-'] and values['-OUTPUT FOLDER-']:
logging.debug(
('Try create Image with values = ' + str(values)))
try:
folder_path = os.path.join(
values['-INPUT FOLDER-'],
)
output_path = values['-OUTPUT FOLDER-']
if output_name is None:
sg.popup_auto_close(
'You didn\'t set a name for the image, it will be named randomly.')
output_name = secrets.token_hex(16)
for n_file in filter_folder(folder_path, ends_with='.java'):
path, file_is_empty = nassi_file(input_path=folder_path + "/" + n_file, output_path=output_path, outputname=output_name, gui=self,
font_filepath=font_filepath, behaviour=exists_choice, types=types, remove_tags=modifier, comments=comments)
if file_is_empty:
sg.popup_annoying('Our interpreter did not find anything. --> blame Kons or yourself!', title='Empty')
if path:
fnames = filter_folder(path)
sg.popup_annoying('Successfully created!', title='Created',
auto_close_duration=2, auto_close=True, text_color='green')
window['-OUTPUT FILE LIST-'].update(fnames)
else:
fnames = filter_folder(output_path, output_name)
sg.popup_annoying('There are some images created!', title='Cancel',
auto_close_duration=2, auto_close=True, text_color='green')
window['-OUTPUT FILE LIST-'].update(fnames)
except JavaSyntaxError as JsE:
logging.error(
('||SyntaxError in Java File|| Failed to create Image with values = ' + str(values)))
sg.popup_error(str(JsE))
except ScopeNotFoundException as SnFe:
logging.error(
('||ScopeNotFoundExeption|| Failed to create Image with values = ' + str(values)))
sg.popup_error(str(SnFe))
except FileNotFoundError as FnFe:
logging.error(
('||FileNotFoundError|| Failed to create Image with values = ' + str(values)))
sg.popup_error(
(str(FnFe) + 'File ' + str(file_path) + ' or ' + str(output_path) + ' or ' + str(font_filepath) + ' is not reachable.'))
except InterpreterException:
logging.error(
('||InterpreterException|| Failed to create Image with values = ' + str(values)))
except Exception as e:
logging.error(
('Failed to create Image with values = ' + str(values)) + str(e))
sg.popup_error(('Failed to create an image of one function correctly. ' + str(e)) + 'There may be some images created. ')
except:
raise
@@ -151,21 +218,19 @@ class Gui:
sg.popup(
'This was made by plexx(Image generation), Weckyy702(Interpreter) and oleting(Frontend). Used Python 3.9.1, Libraries PySimpleGUI and Pillow.', title='Credits')
# handle fun feature
if event == '-DONATE-':
logging.debug(('event = ' + str(event)))
sg.popup_notify(
('You donated $' + str(random.randint(500, 100000000)) + '.'), title='Thanks')
# needed Input
# handle event select output folder
if event == '-OUTPUT FOLDER-':
logging.debug(('event = ' + str(event) +
' value = ' + str(values['-OUTPUT FOLDER-'])))
fnames = output(values['-OUTPUT FOLDER-'])
window['-OUTPUT FILE LIST-'].update(fnames)
try:
logging.debug(('event = ' + str(event) +
' value = ' + str(values['-OUTPUT FOLDER-'])))
fnames = filter_folder(values['-OUTPUT FOLDER-'])
window['-OUTPUT FILE LIST-'].update(fnames)
except Exception as e:
logging.error(str(e))
sg.popup_error(str(e))
elif event == '-OUTPUT FILE LIST-':
logging.debug(('event = ' + str(event) +
' value = ' + str(values['-OUTPUT FILE LIST-'])))
@@ -245,7 +310,7 @@ class Gui:
# handle event REFRESH
if event == '-REFRESH-':
try:
fnames = output(values['-OUTPUT FOLDER-'])
fnames = filter_folder(values['-OUTPUT FOLDER-'])
window['-OUTPUT FILE LIST-'].update(fnames)
except NoPathError:
pass

View File

@@ -1,3 +1,8 @@
"""new_window_layouts.py: create layouts"""
__author__ = "oleting"
import PySimpleGUI as sg
class Layout_std:
@@ -8,18 +13,21 @@ class Layout_std:
sg.Button(button_text='Create Image', key='-CREATE-'),
sg.Button(button_text='Credits', key='-CREDITS-'),
sg.Button(button_text='Settings', key='-SETTINGS-'),
# * fun feature
sg.Button(button_text='Donate', key='-DONATE-'),
]
]
input_column = [
[
sg.Text('Java File'),
sg.Text('Input: single File'),
sg.In(size=(25, 1), enable_events=True, key="-JAVA IN-"),
sg.FileBrowse(file_types=(('Java-File', '*.java'), ('ALL Files',
'*.*')), key='-JAVA FILE-'),
],
[
sg.Text('Input: whole Folder (without subfolders)'),
sg.In(size=(25, 1), enable_events=True, key="-INPUT FOLDER-"),
sg.FolderBrowse(),
],
[
sg.Text('Output Folder'),
sg.In(size=(25, 1), enable_events=True, key="-OUTPUT FOLDER-"),

View File

@@ -1,52 +1,60 @@
"""utils.py: utils for gui.py"""
__author__ = "oleting, Weckyy702"
from errors.custom import NoPathError
from interpreter.NassiShneidermann import NassiShneidermanDiagram, Overwrite_behaviour, OB
from PySimpleGUI import one_line_progress_meter
from typing import Optional
import os
import logging
#types=types, remove_tages=modifier, comments=comments
def nassi(input_path: str, output_path: str, outputname: str, types, remove_tags, comments, gui, behaviour: Overwrite_behaviour, font_filepath: Optional[str]=None):
def nassi_file(input_path: str, output_path: str, outputname: str, types, remove_tags, comments, gui, behaviour: Overwrite_behaviour, font_filepath: Optional[str]=None):
NSD = NassiShneidermanDiagram(gui.debug_mode)
output_directory = output_path + '/' + outputname
output_directory = check_and_create_output_directory(output_path + '/' + outputname)
if font_filepath != None:
NSD.set_font(font_filepath)
custom_tags = {"comments" : comments, "ignore" : remove_tags, "types" : types}
is_empty = NSD.load_from_file(input_path, custom_tags)
for scopes_index in NSD.convert_to_image(output_directory, on_conflict=behaviour):
cancel = one_line_progress_meter('Progress', scopes_index, len(NSD.function_scopes), '-PROGRESSBAR-')
if not cancel:
break
return output_directory, is_empty
def check_and_create_output_directory(output_directory):
try:
if not os.path.exists(output_directory):
os.makedirs(output_directory)
except OSError:
logging.error('Error: Creating directory. ' + output_directory)
except:
except Exception as e:
logging.error(e+ ': ' + output_directory)
raise
custom_tags = {"comments" : comments, "ignore" : remove_tags, "types" : types}
NSD.load_from_file(input_path, custom_tags)
cancel = NSD.convert_to_image(output_directory, on_conflict=behaviour)
if not cancel:
return None
return output_directory
def filter_folder(path, name=None, ends_with=('.png', '.gif')):
def output(output_path, output_name=None):
if output_path == '':
if path == '':
raise NoPathError
if output_name:
output_path = output_path + '/' + output_name
if name:
path = path + '/' + name
try:
file_list = os.listdir(output_path)
file_list = os.listdir(path)
except:
file_list = []
fnames = [
f
for f in file_list
if os.path.isfile(os.path.join(output_path, f))
and f.lower().endswith(('.png', '.gif'))
if os.path.isfile(os.path.join(path, f))
and f.lower().endswith(ends_with)
]
return fnames

403
interpreter/Lexer.py Normal file
View File

@@ -0,0 +1,403 @@
"""Lexer.py: Definition for Lexer class"""
from interpreter.Tokenizer import Tokenizer
from os import linesep
from draw.Iinstruction import *
from typing import List, Optional, Union, Tuple
import logging
from interpreter.function_scope import Function_scope
from interpreter._token import Token, Token_type
from errors.custom import JavaSyntaxError
def print_arr(arr):
print("[")
for elem in arr:
if isinstance(elem, List):
print_arr(elem)
else:
print(elem)
print("]")
class Lexer:
def __init__(self, tokens: List[Token]) -> None:
self._tokens = tokens
self._token_index = 0
self._scopes: List[Function_scope] = []
#in case the tokenizer finds valid tokens in the global scope, they will be saved here
self._global_instructions = []
def _peek(self, offset:int=0) -> Optional[Token]:
if (self._token_index+offset) >= len(self._tokens):
return None
return self._tokens[self._token_index+offset]
def _consume(self):
token = self._peek()
self._token_index+=1
return token
def get_instructions(self):
scopes = []
while self._peek():
line_tokens = self.get_line_tokens()
if self._is_function_def(line_tokens):
func_name, func_return_type, func_args = self._construct_function_header_from_tokens(line_tokens)
current_scope = Function_scope(func_name, func_return_type, func_args)
instructions = self._get_instructions_in_scope()
current_scope._add_instructions(instructions)
scopes.append(current_scope)
else:
#something was declared in global scope
self._global_instructions.append(self._construct_instruction_from_tokens(line_tokens))
self.add_globals_to_scope_list(scopes)
return scopes
def _get_instructions_in_scope(self):
instructions = []
while self._peek():
line_tokens = self.get_line_tokens()
instruction = self._construct_instruction_from_tokens(line_tokens)
if instruction:
instructions.append(instruction)
delimiter_token = line_tokens[-1]
if delimiter_token.type == Token_type.RIGHT_CURLY:
return instructions
raise JavaSyntaxError(f"{self._peek(-1).location}: Missing right curly!")
def get_tokens_until(self, delimiter_types: List[Token_type]) -> List[Token]:
tokens = []
while token := self._consume():
tokens.append(token)
if token.type in delimiter_types:
break
return tokens
def get_line_tokens(self):
return self.get_tokens_until([Token_type.SEMICOLON, Token_type.LEFT_CURLY, Token_type.RIGHT_CURLY])
def add_globals_to_scope_list(self, scope_list: List[Function_scope]):
global_scope = Function_scope("<Global scope>", "void", [])
global_scope._add_instructions(self._global_instructions)
scope_list.append(global_scope)
def _is_function_def(self, tokens: List[Token]) -> bool:
#if token list is of shape TYPE_NAME IDENTIFIER ( ... {
return tokens[0].type == Token_type.TYPE_NAME and tokens[1].type == Token_type.UNKNOWN and tokens[2].type == Token_type.LEFT_PAREN and tokens[-1].type == Token_type.LEFT_CURLY
def _construct_instruction_from_tokens(self, tokens: List[Token]):
instruction_token = tokens[0]
if instruction_token.type == Token_type.IF_STATEMENT:
return self._handle_if_construct(tokens)
elif instruction_token.type == Token_type.WHILE_STATEMENT:
return self._handle_while_construct(tokens)
elif instruction_token.type == Token_type.DO_WHILE_STATEMENT:
return self._handle_do_while_construct(tokens)
elif instruction_token.type == Token_type.FOR_STATEMENT:
return self._handle_for_construct(tokens)
elif instruction_token.type == Token_type.TYPE_NAME:
return self._handle_type_name_construct(tokens)
elif instruction_token.type == Token_type.UNKNOWN:
return self._handle_generic_construct(tokens)
def _construct_function_header_from_tokens(self, tokens: List[Token]) -> Tuple[str, str, List[str]]:
_ensure_correct_function_structure(tokens)
function_return_type = tokens[0].content
function_name = tokens[1].content
argument_list = _get_function_argument_list_from_tokens(tokens[3:-2])
return function_name, function_return_type, argument_list
def _construct_variable_def_from_tokens(self, tokens: List[Token]) -> str:
_ensure_correct_variable_structure(tokens)
variable_type = tokens[0].content
variable_name = tokens[1].content
if tokens[2].type == Token_type.SEMICOLON:
return f"declare variable '{variable_name}' of type {variable_type}"
variable_value = self._construct_source_line_from_tokens(tokens[3:])
return f"declare variable '{variable_name}' of type {variable_type} with value {variable_value}"
def _construct_source_line_from_tokens(self, tokens: List[Token]) -> str:
"""TODO: make this function smarter"""
line = ""
for token in tokens:
if token.type == Token_type.SEMICOLON:
break
line += token.content + ' '
return line[:-1] #ignore the space after the last instruction text
"""Handler functions for different types of language structures"""
def _handle_if_construct(self, tokens: List[Token]):
logging.debug("Found if construct")
_ensure_correct_if_structure(tokens)
condition_str = self._construct_source_line_from_tokens(tokens[2:-2])
true_case = self._get_instructions_in_scope()
false_case = self._handle_else_construct()
return if_instruction(condition_str, true_case, false_case)
def _handle_else_construct(self):
if self._peek().type == Token_type.ELSE_STATEMENT:
if self._peek(1).type == Token_type.IF_STATEMENT:
logging.debug("Found if-else construct")
else_if_tokens = self.get_line_tokens()[1:]
return [self._handle_if_construct(else_if_tokens)]
else:
logging.debug("Found else construct")
self.get_line_tokens()
return self._get_instructions_in_scope()
return None
def _handle_while_construct(self, tokens: List[Token]):
logging.debug("Found while construct")
_ensure_correct_while_structure(tokens)
condtion_str = self._construct_source_line_from_tokens(tokens[2:-2])
loop_instructions = self._get_instructions_in_scope()
return while_instruction_front(condtion_str, loop_instructions)
def _handle_do_while_construct(self, tokens: List[Token]):
logging.debug("Found do-while construct")
_ensure_correct_do_while_structure_part_1(tokens)
loop_instructions = self._get_instructions_in_scope()
while_tokens = self.get_line_tokens()
_ensure_correct_do_while_structure_part_2(while_tokens)
condtion_str = self._construct_source_line_from_tokens(while_tokens[2:-2])
return while_instruction_back(condtion_str, loop_instructions)
def _handle_for_construct(self, tokens: List[Token]):
logging.debug("Found for construct")
tokens.extend(self.get_tokens_until([Token_type.LEFT_CURLY]))
_ensure_correct_for_structure(tokens)
variable_tokens, condition_tokens, increment_tokens = _get_for_arguments_from_tokens(tokens[2:])
variable_str = ""
if len(variable_tokens) > 1: #if we got more than just a semicolon
variable_str = self._construct_variable_def_from_tokens(variable_tokens)
condition_str = "true"
if condition_tokens:
condition_str = self._construct_source_line_from_tokens(condition_tokens)
increment_instruction = None
if increment_tokens:
increment_instruction = generic_instruction(self._construct_source_line_from_tokens(increment_tokens))
loop_instructions = self._get_instructions_in_scope()
if increment_instruction:
loop_instructions.append(increment_instruction)
return for_instruction(variable_str, condition_str, loop_instructions)
def _handle_type_name_construct(self, tokens: List[Token]):
logging.debug("Found Type name construct")
return generic_instruction(self._construct_variable_def_from_tokens(tokens))
def _handle_generic_construct(self, tokens: List[Token]):
logging.debug("Found generic instruction")
return generic_instruction(self._construct_source_line_from_tokens(tokens))
def _ensure_correct_function_structure(tokens: List[Token]):
#function structure: TYPE_NAME IDENTIFIER ( ... ) {
if len(tokens) < 5:
raise JavaSyntaxError(f"{tokens[0].location}: Ill-formed function declaration! Expected at least 5 tokens, got {len(tokens)}")
if tokens[-1].type != Token_type.LEFT_CURLY:
raise JavaSyntaxError(f"{tokens[-1].location}: Ill-formed function declaration! Expected last token to be LEFT_CURLY, got {str(tokens[-1].type)}")
if tokens[1].type != Token_type.UNKNOWN:
raise JavaSyntaxError(f"{tokens[1].location}: Illegal token after function return type! Expected UNKNWON, got {str(tokens[1].type)}")
if tokens[2].type != Token_type.LEFT_PAREN:
raise JavaSyntaxError(f"{tokens[2].location}: Illegal token after funtion name! Expected LEFT_CURLY, got {str(tokens[2].type)}")
if tokens[-2].type != Token_type.RIGTH_PAREN:
raise JavaSyntaxError(f"{tokens[-2].location}: Illegal token after function parameter list! Expected RIGHT_PAREN, got {str(tokens[-2].type)}")
def _ensure_correct_variable_structure(tokens: List[Token]):
#variable structure: TYPE_NAME IDENTIFIER ;|( = EXPRESSION;)
if len(tokens) < 3:
raise JavaSyntaxError(f"{tokens[0].location}: Ill-formed type construct! Expected at least 3 tokens, got {len(tokens)}")
if tokens[1].type != Token_type.UNKNOWN:
raise JavaSyntaxError(f"{tokens[1].location}: Illegal token after type name! Expected UNKNOWN, got {str(tokens[1].type)}")
if not tokens[2].type in [Token_type.SEMICOLON, Token_type.EQUAL_SIGN]:
raise JavaSyntaxError(f"{tokens[2].location}: Illegal token after variable name! Expected SEMICOLON or EQUAL_SIGN, got {str(tokens[2].type)}")
if tokens[2].type == Token_type.EQUAL_SIGN and len(tokens) < 5:
raise JavaSyntaxError(f"{tokens[2].location}: Ill-formed assignment expression! Expected at least 5 tokens, got {len(tokens)}")
def _ensure_correct_if_structure(tokens: List[Token]):
#if structure: IF ( ... ) { <-- the opening curly is technically not needed, but we require it anyways
if len(tokens) < 5:
raise JavaSyntaxError(f"{tokens[0].location}: Ill-formed if construct! Expected at least 5 tokens, got {len(tokens)}")
if tokens[-1].type != Token_type.LEFT_CURLY:
raise JavaSyntaxError(f"{tokens[-1].location}: Ill-formed if construct! Expected last token to be LEFT_CURLY, got {str(tokens[-1].type)}")
if tokens[1].type != Token_type.LEFT_PAREN:
raise JavaSyntaxError(f"{tokens[1].location}: Illegal token after if token! Expected LEFT_PAREN, got {str(tokens[1].type)}")
if tokens[-2].type != Token_type.RIGTH_PAREN:
raise JavaSyntaxError(f"{tokens[-2].location}: Illegal token after conditional expression! Expected RIGHT_PAREN, got {str(tokens[-2].type)}")
def _ensure_correct_while_structure(tokens: List[Token]):
#while structure: WHILE ( ... ) { <-- might not be required by the standard, but is required by us
if len(tokens) < 5:
raise JavaSyntaxError(f"{tokens[0].location}: Ill-formed while construct! Expected at least 5 tokens, got {len(tokens)}")
if tokens[-1].type != Token_type.LEFT_CURLY:
raise JavaSyntaxError(f"{tokens[-1].location}: Ill-formed while construct! Expected last token to be LEFT_CURLY, got {str(tokens[-1].type)}")
if tokens[1].type != Token_type.LEFT_PAREN:
raise JavaSyntaxError(f"{tokens[1].location}: Illegal token after while token! Expected LEFT_PAREN, got {str(tokens[1].type)}")
if tokens[-2].type != Token_type.RIGTH_PAREN:
raise JavaSyntaxError(f"{tokens[-2].location}: Illegal token after while condition! Expected RIGHT_PAREN, got {str(tokens[-2].type)}")
def _ensure_correct_do_while_structure_part_1(tokens: List[Token]):
#do-while structure: do{
if len(tokens) != 2:
raise JavaSyntaxError(f"{tokens[0].location}: Ill-formed do-while construct! Expected 2 tokens, got {len(tokens)}")
if tokens[1].type != Token_type.LEFT_CURLY:
raise JavaSyntaxError(f"Illegal token after do token! Expected LEFT_CURLY, got {str(tokens[1].type)}")
def _ensure_correct_do_while_structure_part_2(tokens: List[Token]):
#do-while structure: while( ... );
if len(tokens) < 5:
raise JavaSyntaxError(f"{tokens[0].location}: Ill-formed do while contruct! Expected at least 5 tokens, got {len(tokens)}")
if tokens[0].type != Token_type.WHILE_STATEMENT:
raise JavaSyntaxError(f"{tokens[0].location}: Illegal token after do block! Expected WHILE_STATEMENT, got {str(tokens[1].type)}")
if tokens[-1].type != Token_type.SEMICOLON:
raise JavaSyntaxError(f"{tokens[-1].location}: Ill-formed do-while construct! Expected last token to be SEMICOLON, got {str(tokens[-1].type)}")
if tokens[1].type != Token_type.LEFT_PAREN:
raise JavaSyntaxError(f"{tokens[1].location}: Illegal token after while token! Expected LEFT_PAREN, got {str(tokens[1].type)}")
if tokens[-2].type != Token_type.RIGTH_PAREN:
raise JavaSyntaxError(f"{tokens[-2].location}: Illegal token after do-while condition! Expected RIGHT_PAREN, got {str(tokens[-2].type)}")
def _ensure_correct_for_structure(tokens: List[Token]):
#for structure: for(...?;...?;...?) {
if len(tokens) < 6:
raise JavaSyntaxError(f"{tokens[0].location}: Illf-formed for loop construct! Expected at least 6 tokens, got {len(tokens)}")
if tokens[-1].type != Token_type.LEFT_CURLY:
raise JavaSyntaxError(f"{tokens[-1].location}: Ill-formed for loop construct! Expected last token to be LEFT_CURLY, got {str(tokens[-1].type)}")
if tokens[1].type != Token_type.LEFT_PAREN:
raise JavaSyntaxError(f"{tokens[1].location}: Illegal token after for token! Expected LEFT_PAREN, got {str(tokens[1].type)}")
if tokens[-2].type != Token_type.RIGTH_PAREN:
raise JavaSyntaxError(f"{tokens[-2].location}: Illegal token after for loop increment! Expected RIGHT_PAREN, got {str(tokens[-2].type)}")
if ( semicolon_count := tokens.count(Token(Token_type.SEMICOLON)) ) != 2:
raise JavaSyntaxError(f"Ill-formed for loop construct! Expected exactly 2 SEMICOLON tokens, got {semicolon_count}")
def _get_function_argument_list_from_tokens(tokens: List[Token]) -> List[str]:
arg_tokens = _get_seperated_token_list(tokens, [Token_type.COMMA])
args = []
for arg in arg_tokens:
arg_str = ""
for token in arg:
arg_str += token.content + ' '
arg_str = arg_str[:-1]
args.append(arg_str)
return args
def _get_seperated_token_list(tokens: List[Token], seperator_types: List[Token_type]) -> List[List[Token]]:
token_segments = []
tokens_in_segment = []
for token in tokens:
if token.type in seperator_types:
token_segments.append(tokens_in_segment)
tokens_in_segment = []
continue
tokens_in_segment.append(token)
token_segments.append(tokens_in_segment)
return token_segments
def _get_for_arguments_from_tokens(tokens: List[Token]) -> Tuple[List[Token], List[Token], List[Token]]:
variable_tokens = []
condition_tokens = []
increment_tokens = []
token_index = 0
while True:
token = tokens[token_index]
token_index += 1
variable_tokens.append(token)
if token.type == Token_type.SEMICOLON:
break
while True:
token = tokens[token_index]
token_index += 1
if token.type == Token_type.SEMICOLON:
break
condition_tokens.append(token)
while True:
token = tokens[token_index]
token_index += 1
if token.type == Token_type.LEFT_CURLY:
break
increment_tokens.append(token)
return variable_tokens, condition_tokens, increment_tokens[:-1]

View File

@@ -1,19 +1,24 @@
from os import stat
from interpreter.interpret_source import Function_scope
"""NassiShneidermann.py: Classes for the Java Instruction found by the Interpreter"""
__author__ = "Weckyy702"
from typing import Dict, List, Optional
# from PySimpleGUI import one_line_progress_meter
import logging
from enum import IntEnum
import os.path
import secrets
from interpreter.interpret_source import JavaInterpreter
from interpreter.Tokenizer import Tokenizer
from interpreter.Lexer import Lexer
from interpreter.function_scope import Function_scope
from draw.code_to_image_wrapper import NSD_writer
import draw.code_to_image as cti
class Overwrite_behaviour(IntEnum):
SKIP = 0
OVERWWRITE = 1
OVERWRITE = 1
RANDOM_NAME = 2
OB = Overwrite_behaviour
@@ -22,12 +27,8 @@ class NassiShneidermanDiagram:
def __init__(self, do_debug: bool):
self.function_scopes: List[Function_scope] = []
self.init_logging(do_debug)
@staticmethod
def init_logging(debug: bool):
logLevel = logging.INFO
if debug:
if do_debug:
logLevel = logging.DEBUG
logging.basicConfig(force=True, level=logLevel)
@@ -38,36 +39,34 @@ class NassiShneidermanDiagram:
@staticmethod
def _save_scope(scope: Function_scope, output_path: str):
y_size = scope.get_height()
x_size = scope.get_width()
with NSD_writer(output_path, x_size, y_size):
x, y = 0, 0
width = scope.get_width()
height = scope.get_height()
with NSD_writer(output_path, width, height):
y = 0
for instruction in scope:
x, y = instruction.to_image(x, y, x_size)
print(instruction.instruction_text)
y = instruction.convert_to_image(0, y, width)
@staticmethod
def check_conflicts(filepath:str, behavoiur: Overwrite_behaviour):
if os.path.exists(filepath + ".png"):
if behavoiur == OB.SKIP:
return None
elif behavoiur == OB.OVERWWRITE:
elif behavoiur == OB.OVERWRITE:
return filepath
else:
while os.path.exists(filepath+".png"):
filepath = filepath + str(secrets.token_hex(1))
filepath += str(secrets.token_hex(1))
return filepath
return filepath
def convert_to_image(self, output_path: str, on_conflict: Overwrite_behaviour=OB.SKIP) -> bool:
number_of_item = 1
def convert_to_image(self, output_path: str, on_conflict: Overwrite_behaviour=OB.SKIP):
i = 0
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
filepath = f"{output_path}/{scope.name}"
filepath = self.check_conflicts(filepath, on_conflict)
if filepath is not None:
logging.info(f"Saving NSD to {filepath}.png...")
@@ -79,9 +78,22 @@ class NassiShneidermanDiagram:
except:
logging.error(f"Failed to save image {filepath}. Unknown error")
raise
return True
yield i+1
i+=1
def load_from_file(self, filepath:str, itp_custom_tags: Optional[Dict[str, List[str]]]):
itp = JavaInterpreter(filepath)
itp.reset_tags(itp_custom_tags)
self.function_scopes = itp.load_instruction_scopes()
tokenizer = Tokenizer(filepath)
tokens = tokenizer.get_tokens()
lexer = Lexer(tokens)
self.function_scopes = lexer.get_instructions()[:-1]
if not self.function_scopes:
return True
else:
return False

112
interpreter/Tokenizer.py Normal file
View File

@@ -0,0 +1,112 @@
"""Tokenizer.py: Definition for Tokenizer class"""
from errors.custom import JavaSyntaxError
import logging
import re
from typing import List, Optional
from interpreter._token import Token, make_token, SourceLocation
class Tokenizer:
"""This class will take the provided source file and convert it to a list of tokens"""
TOKEN_MATCH = re.compile(r"""\(|\)|\{|\}|;|(\n)|\+|-|\*|/|<|>|,| """)
def __init__(self, file_name: str) -> None:
with open(file_name) as f:
self.source_text = f.read()
self.source_index = 0
self.line_number = 1
self.column_number = 0
self.source_text = re.sub("(private)|(public)|(protected)|(final)", "", self.source_text)
self.type_name_pattern = re.compile('(char)|(int)|(void)|(double)|(boolean)|(Pixel)|(String)') #TODO: make this modular
self._filename = file_name
self._left_curly_number=0
self._right_curly_number=0
def get_tokens(self) -> List[Token]:
tokens = []
while char := self._consume():
if char.isspace():
continue
if self._handle_comments(char):
continue
tag = self._get_token(char)
logging.debug(f"found tag \"{tag}\" on line {self.line_number}")
if tag == "{":
self._left_curly_number+=1
elif tag == "}":
self._right_curly_number+=1
tokens.append(make_token(tag, SourceLocation(self._filename, self.line_number, self.column_number), self.type_name_pattern))
if self._left_curly_number != self._right_curly_number:
raise JavaSyntaxError(f"Ill-formed Java program! Expected equal number of '{'{'}' and '{'}'}' tokens, got {self._left_curly_number} and {self._right_curly_number}")
return tokens
def _get_token(self, char: str) -> str:
token = char
if not re.match(Tokenizer.TOKEN_MATCH, token):
while (token_char := self._peek()):
if re.match(Tokenizer.TOKEN_MATCH, token_char):
break
token += self._consume()
return token
def _handle_comments(self, char: str) -> bool:
if char == '/' and self._peek() == '/':
self._get_line() #skip the entire line
return True
elif char == '/' and self._peek() == '*':
self._consume()
self._consume_multiline_comment()
return True
return False
def _get_line(self) -> str:
return self._consume_until('\n')
def _peek(self, offset:int = 0) -> str:
if (self.source_index + offset) >= len(self.source_text):
return ''
char = self.source_text[self.source_index]
return char
def _consume(self) -> str:
char = self._peek()
if char == '\n':
self.line_number += 1
self.column_number = 1
self.source_index += 1
self.column_number += 1
return char
def _consume_multiline_comment(self):
while self._peek():
if self._consume() == '*' and self._peek() == '/':
self._consume()
break
def _consume_until(self, end_tag: str) -> str:
res = ""
while self._peek() and (char:= self._consume()) != end_tag:
res += char
return res

91
interpreter/_token.py Normal file
View File

@@ -0,0 +1,91 @@
"""Private definitions for Token class used by the Lexer"""
import re
from dataclasses import dataclass, field
from enum import IntEnum
from typing import Union
NUMERIC_CONSTANT_PATTERN = re.compile(r"""([0-9]+)|(true)|(false)""")
KEYWORD_PATTERN = re.compile(r"""(return)$|(continue)$|(break)$|(new)$""")
STRING_LITERAL_PATTERN = re.compile(r"""('|\")(.*)(\"|')""")
MATH_OP_PATTERN = re.compile(r"""\+|-|\*|/|<|>""")
class Token_type(IntEnum):
UNKNOWN=-1 #maybe this should be renamed to IDENTIFIER
LEFT_PAREN=0,
RIGTH_PAREN=1,
LEFT_CURLY=2,
RIGHT_CURLY=3,
LEFT_BRACKET=4,
RIGHT_BRACKET=5,
COMMA=6,
EQUAL_SIGN=7,
SEMICOLON=8
MATH_OP=9
NUMERIC_CONSTANT=10,
IF_STATEMENT=11,
ELSE_STATEMENT=12,
WHILE_STATEMENT=13,
DO_WHILE_STATEMENT=14,
FOR_STATEMENT=15,
KEY_WORD=16,
STRING_LITERAL=17
TYPE_NAME=18
@dataclass(frozen=True)
class SourceLocation:
file: str
line: int
column: int
def __str__(self) -> str:
return f"File {self.file} {self.line}:{self.column}"
@dataclass(frozen=True, eq=True)
class Token:
type: Token_type
location: SourceLocation = field(compare=False, default=SourceLocation("", 0, 0))
content: str = field(compare=False, default="")
def make_token(tag: str, location: SourceLocation, type_name_pattern:re.Pattern) -> Token:
"""Construct a token object with the provided tag and source location"""
if tag == '(':
return Token(Token_type.LEFT_PAREN, location, tag)
elif tag == ')':
return Token(Token_type.RIGTH_PAREN, location, tag)
elif tag == '{':
return Token(Token_type.LEFT_CURLY, location, tag)
elif tag == '}':
return Token(Token_type.RIGHT_CURLY, location, tag)
elif tag == '[':
return Token(Token_type.LEFT_BRACKET, location, tag)
elif tag == ']':
return Token(Token_type.RIGHT_BRACKET, location, tag)
elif tag == ',':
return Token(Token_type.COMMA, location, tag)
elif tag == '=':
return Token(Token_type.EQUAL_SIGN, location, tag)
elif tag == ';':
return Token(Token_type.SEMICOLON, location, tag)
elif MATH_OP_PATTERN.match(tag):
return Token(Token_type.MATH_OP, location, tag)
elif NUMERIC_CONSTANT_PATTERN.match(tag):
return Token(Token_type.NUMERIC_CONSTANT, location, tag)
elif tag == "if":
return Token(Token_type.IF_STATEMENT, location, tag)
elif tag == "else":
return Token(Token_type.ELSE_STATEMENT, location, tag)
elif tag == "while":
return Token(Token_type.WHILE_STATEMENT, location, tag)
elif tag == "do":
return Token(Token_type.DO_WHILE_STATEMENT, location, tag)
elif tag == "for":
return Token(Token_type.FOR_STATEMENT, location, tag)
elif KEYWORD_PATTERN.match(tag):
return Token(Token_type.KEY_WORD, location, tag)
elif STRING_LITERAL_PATTERN.match(tag):
return Token(Token_type.STRING_LITERAL, location, tag)
elif type_name_pattern.match(tag):
return Token(Token_type.TYPE_NAME, location, tag)
else:
return Token(Token_type.UNKNOWN, location, tag)

View File

@@ -0,0 +1,36 @@
"""function_scope.py: Class for Function scopes"""
__author__ = "Weckyy702"
from typing import Iterable, List
from draw.Iinstruction import instruction
class Function_scope(Iterable):
"""This class serves as a container for Instructions"""
def __init__(self, name: str, return_type: str, args: List[str]) -> None:
self.contents = []
self.name = name
self.return_type = return_type
self.args = args
def get_height(self) -> int:
h = 0
for inst in self.contents:
h += inst.get_block_height()
return max(h, 5) #a NSD has to be at least 5 pixels tall
def get_width(self) -> int:
w = 200 #minimum width for every block
for inst in self.contents:
w = max(w, inst.get_block_width())
return w
def _add_instruction(self, inst: instruction):
self.contents.append(inst)
def _add_instructions(self, inst: List[instruction]):
self.contents.extend(inst)
def __iter__(self):
return self.contents.__iter__()

View File

@@ -1,10 +1,20 @@
"""interpret_source.py: #TODO"""
__author__ = "Weckyy702"
import logging
import re
from typing import Dict, List, Match, Tuple, Union
from typing import Dict, List, Match, Tuple, Union, Iterable
from errors.custom import InterpreterException, JavaSyntaxError, ScopeNotFoundException
from draw.Iinstruction import *
<<<<<<< HEAD
from interpreter.function_scope import *
=======
from interpreter.Function_scope import Function_scope
>>>>>>> main
logging.warning("""Because the Interpreter is still WIP, some Java language features are not supported. These include:
*foreach loops (will throw JavaSyntaxError)
@@ -191,7 +201,6 @@ class JavaInterpreter:
instructions.append(for_instruction("while " + cond, child_instructions))
return instructions, idx
except IndexError:
raise JavaSyntaxError("Ill-formed for loop construct!")
except:
@@ -206,7 +215,7 @@ class JavaInterpreter:
return generic_instruction(f"declare variable '{var_name}' of type {var_type}"), idx
return generic_instruction(f"declare variable '{var_name}' of type {var_type} with value {var_value}"), idx
def _handle_instruction(self, line: str, idx:int) -> Tuple[Union[Iinstruction, List[Iinstruction]], int]:
def _handle_instruction(self, line: str, idx:int) -> Tuple[Union[instruction, List[instruction]], int]:
if line.startswith("while("):
logging.debug("Found while construct in line: %i", idx+1)
return self._handle_while(line, idx)
@@ -231,8 +240,8 @@ class JavaInterpreter:
logging.debug("Found generic instruction in line %i", idx+1)
return generic_instruction(line), idx
def _get_instructions_in_scope(self, idx: int=0) -> Tuple[List[Iinstruction], int]:
scope: List[Iinstruction] = []
def _get_instructions_in_scope(self, idx: int=0) -> Tuple[List[instruction], int]:
scope: List[instruction] = []
i = idx
while i < len(self._lines):
line = self._lines[i]
@@ -262,7 +271,7 @@ class JavaInterpreter:
fname = groups["name"]
return ftype, fname, fargs
def _get_function_instructions(self, function_header: str) -> List[Iinstruction]:
def _get_function_instructions(self, function_header: str) -> List[instruction]:
idx = self._lines.index(function_header)
brace_offset = self._get_scope_start_offset(idx)
return self._get_instructions_in_scope(idx+brace_offset)[0]

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
PySimpleGUI

View File

@@ -1,281 +0,0 @@
importgreenfoot.*;//(World,Actor,GreenfootImage,GreenfootandMouseInfo)
classRoverextendsActor
{
Displayanzeige;
/**
*thisfunctionistobeimplementedbytheuser
*dependingontheneededactions
*/
voidact()
{
S66Nr3(7);
}
voidfahreUmHuegel(Stringrichtung)
{
Stringpri;
Stringsec;
if(richtung.equals("Hoch")){
pri="links";
sec="rechts";
}else{
if(richtung.equals("Runter")){
pri="rechts";
sec="links";
}else{
nachricht("JUNGEDUSPAST!");
return;
}
}
drehe(pri);
fahre();
drehe(sec);
fahre();
fahre();
drehe(sec);
fahre();
drehe(pri);
}
voidfahreBisHuegel()
{
while(!huegelVorhanden("vorne"))
{
fahre();
}
}
voidfahreZeileDreheHoch()
{
fahreBisHuegel();
fahreUmHuegel("Hoch");
fahreBisHuegel();
drehe("um");
fahreBisHuegel();
fahreUmHuegel("Runter");
fahreBisHuegel();
drehe("rechts");
fahre();
drehe("rechts");
}
voidfahreZeileDreheRunter(booleangeheInNächsteZeile)
{
fahreBisHuegel();
fahreUmHuegel("Runter");
fahreBisHuegel();
drehe("um");
fahreBisHuegel();
fahreUmHuegel("Hoch");
fahreBisHuegel();
if(geheInNächsteZeile){
drehe("rechts");
fahre();
drehe("rechts");
}else{
drehe("um");
}
}
voidS66Nr3(intanzahlZeilen)
{
if(anzahlZeilen<3){
nachricht("IchmussmindestensdreiZeilenfahren!:(");
return;
}
fahreZeileDreheHoch();
for(inti=1;i<anzahlZeilen-1;i++){
fahreZeileDreheRunter(true);
}
fahreZeileDreheRunter(false);
}
/**
*DerRoverbewegtsicheinFeldinFahrtrichtungweiter.
*SolltesichinFahrtrichtungeinObjektderKlasseHuegelbefindenoderersichanderGrenzederWeltbefinden,
*dannerscheinteineentsprechendeMeldungaufdemDisplay.
*/
voidfahre()
{
intposX=getX();
intposY=getY();
if(huegelVorhanden("vorne"))
{
nachricht("Zusteil!");
}
elseif(getRotation()==270&&getY()==1)
{
nachricht("Ichkannmichnichtbewegen");
}
else
{
move(1);
Greenfoot.delay(1);
}
if(posX==getX()&&posY==getY()&&!huegelVorhanden("vorne"))
{
nachricht("Ichkannmichnichtbewegen");
}
}
/**
*DerRoverdrehtsichum90GradindieRichtung,diemitrichtung(ᅵlinksᅵoderᅵrechtsᅵ)ᅵbergebenwurde.
*SollteeinandererText(String)als"rechts"oder"links"ᅵbergebenwerden,dannerscheinteineentsprechendeMeldungaufdemDisplay.
*/
voiddrehe(Stringrichtung)
{
if(richtung.equals("rechts")){
setRotation(getRotation()+90);
}elseif(richtung.equals("links")){
setRotation(getRotation()-90);
}elseif(richtung.equals("um")){
setRotation(getRotation()+180);
}else{
nachricht("KeinenKorrekteRichtunggegeben!");
}
}
/**
*DerRovergibtdurcheinenWahrheitswert(trueoderfalse)zurᅵck,obsichaufseinerPositioneinObjektderKlasseGesteinbefindet.
*EineentsprechendeMeldungerscheintauchaufdemDisplay.
*/
booleangesteinVorhanden()
{
if(getOneIntersectingObject(Gestein.class)!=null)
{
nachricht("Gesteingefunden!");
returntrue;
}
returnfalse;
}
/**
*DerRoverᅵberprᅵft,obsichinrichtung("rechts","links",oder"vorne")einObjektderKlasseHuegelbefindet.
*DasErgebniswirdaufdemDisplayangezeigt.
*SollteeinandererText(String)als"rechts","links"oder"vorne"ᅵbergebenwerden,dannerscheinteineentsprechendeMeldungaufdemDisplay.
*/
booleanhuegelVorhanden(Stringrichtung)
{
introt=getRotation();
if(richtung=="vorne"&&rot==0||richtung=="rechts"&&rot==270||richtung=="links"&&rot==90)
{
if(getOneObjectAtOffset(1,0,Huegel.class)!=null&&((Huegel)getOneObjectAtOffset(1,0,Huegel.class)).getSteigung()>30)
{
returntrue;
}
}
if(richtung=="vorne"&&rot==180||richtung=="rechts"&&rot==90||richtung=="links"&&rot==270)
{
if(getOneObjectAtOffset(-1,0,Huegel.class)!=null&&((Huegel)getOneObjectAtOffset(-1,0,Huegel.class)).getSteigung()>30)
{
returntrue;
}
}
if(richtung=="vorne"&&rot==90||richtung=="rechts"&&rot==0||richtung=="links"&&rot==180)
{
if(getOneObjectAtOffset(0,1,Huegel.class)!=null&&((Huegel)getOneObjectAtOffset(0,1,Huegel.class)).getSteigung()>30)
{
returntrue;
}
}
if(richtung=="vorne"&&rot==270||richtung=="rechts"&&rot==180||richtung=="links"&&rot==0)
{
if(getOneObjectAtOffset(0,-1,Huegel.class)!=null&&((Huegel)getOneObjectAtOffset(0,-1,Huegel.class)).getSteigung()>30)
{
returntrue;
}
}
if(richtung!="vorne"&&richtung!="links"&&richtung!="rechts")
{
nachricht("Befehlnichtkorrekt!");
}
returnfalse;
}
/**
*DerRoverermitteltdenWassergehaltdesGesteinsaufseinerPositionundgibtdiesenaufdemDisplayaus.
*SolltekeinObjektderKlasseGesteinvorhandensein,dannerscheinteineentsprechendeMeldungaufdemDisplay.
*/
voidanalysiereGestein()
{
if(gesteinVorhanden())
{
nachricht("Gesteinuntersucht!Wassergehaltist"+((Gestein)getOneIntersectingObject(Gestein.class)).getWassergehalt()+"%.");
Greenfoot.delay(1);
removeTouching(Gestein.class);
}
else
{
nachricht("HieristkeinGestein");
}
}
/**
*DerRovererzeugteinObjektderKlasseᅵMarkierungᅵaufseinerPosition.
*/
voidsetzeMarke()
{
getWorld().addObject(newMarke(),getX(),getY());
}
/**
**DerRovergibtdurcheinenWahrheitswert(trueoderfalse)zurᅵck,obsichaufseinerPositioneinObjektderMarkebefindet.
*EineentsprechendeMeldungerscheintauchaufdemDisplay.
*/
booleanmarkeVorhanden()
{
if(getOneIntersectingObject(Marke.class)!=null)
{
returntrue;
}
returnfalse;
}
voidentferneMarke()
{
if(markeVorhanden())
{
removeTouching(Marke.class);
}
}
voidnachricht(StringpText)
{
if(anzeige!=null)
{
anzeige.anzeigen(pText);
Greenfoot.delay(1);
anzeige.loeschen();
}
}
voiddisplayAusschalten()
{
getWorld().removeObject(anzeige);
}
voidaddedToWorld(Worldworld)
{
setImage("images/rover.png");
world=getWorld();
anzeige=newDisplay();
anzeige.setImage("images/nachricht.png");
world.addObject(anzeige,7,0);
if(getY()==0)
{
setLocation(getX(),1);
}
anzeige.anzeigen("Ichbinbereit");
}
classDisplayextendsActor
{
GreenfootImagebild;
Display()
{
bild=getImage();
}
voidact()
{
}
voidanzeigen(StringpText)
{
loeschen();
getImage().drawImage(newGreenfootImage(pText,25,Color.BLACK,newColor(0,0,0,0)),10,10);
}
voidloeschen()
{
getImage().clear();
setImage("images/nachricht.png");
}
}
classDirection{
Direction(intval){
this.value=val;
}
intvalue;
};
}

10
run.py
View File

@@ -1,10 +1,12 @@
#!/usr/bin/env python
from gui.gui import Gui
import sys
do_debug = "--debug" in sys.argv
"""run.py: entrypoint"""
Gui(theme='DarkGrey11', debug_mode=do_debug)
__author__ = "oleting, Weckyy702"
from gui.gui import Gui as gui
from sys import argv
do_debug = "--debug" in argv
gui(theme='DarkGrey11', debug_mode=do_debug)

View File

@@ -1,7 +0,0 @@
from web_app import create_app
app = create_app()
if __name__ == '__main__':
app.run(port=7467 ,debug=False)

Binary file not shown.

Binary file not shown.

View File

@@ -1,15 +0,0 @@
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

View File

@@ -1,2 +0,0 @@
class Config():
SECRET_KEY = '4542bae72a9fefada779b8c3fc68a826'

View File

@@ -1,23 +0,0 @@
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/501.html'), 501

View File

@@ -1,12 +0,0 @@
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')

View File

@@ -1,99 +0,0 @@
from flask.helpers import send_file
from flask import render_template, abort, flash, Blueprint
from web_app.main.forms import UploadJavaForm
from errors.custom import JavaSyntaxError, ScopeNotFoundException, InterpreterException, NoPathError
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/')))
try:
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)
except JavaSyntaxError as JsE:
flash((str(JsE)))
except ScopeNotFoundException as SnFe:
flash((str(SnFe)))
except FileNotFoundError as FnFe:
flash(str(FnFe))
except InterpreterException as iE:
flash(str(iE))
except Exception as e:
flash(('Failed to create an image of one funktion correctly. ' + str(e)) + 'There may be some images created. ')
except:
raise
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)

View File

@@ -1,90 +0,0 @@
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;
}

View File

@@ -1,7 +0,0 @@
{% extends 'layout.html' %}
{% block content %}
<head><meta http-equiv="refresh" content="2; URL=https://ole-siepmann.de/startseite/datenschutzerklaerung/"></head>
<h1 class="black-text">Datenschutz</h1>
<h5 class="black-text">Sie werden jeden Moment weitergeleitet!</h5>
<p class="black-text">Falls dies nicht der Fall ist, hier die Zieladresse https://ole-siepmann.de/startseite/datenschutzerklaerung/ an die Sie weitergeleitet werden.</p>
{% endblock content %}

View File

@@ -1,7 +0,0 @@
{% extends 'layout.html' %}
{% block content %}
<div class="content-section">
<h1>Fehler 403</h1>
<h5>Oops. Das dürfen Sie nicht!</h5>
</div>
{% endblock content %}

View File

@@ -1,8 +0,0 @@
{% extends 'layout.html' %}
{% block content %}
<div class="content-section">
<h1>Fehler 404</h1>
<h5>Oops. Diese Seite existiert nicht</h5>
<p>Hier gibt es nichts zusehen, suchen Sie an einem anderen Ort!</p>
</div>
{% endblock content %}

View File

@@ -1,8 +0,0 @@
{% extends 'layout.html' %}
{% block content %}
<div class="content-section">
<h1>Funktion nicht fertig.</h1>
<h5>Oops. Ole hat diese Funktion der Webseite noch nicht fertig gestellt.</h5>
<p>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.</p>
</div>
{% endblock content %}

View File

@@ -1,8 +0,0 @@
{% extends 'layout.html' %}
{% block content %}
<div class="content-section">
<h1>Fehler 500</h1>
<h5>Oops. Ole oder Kons haben was falsch gemacht</h5>
<p>Versuch es in naher Zukunft nochmal.</p>
</div>
{% endblock content %}

View File

@@ -1,8 +0,0 @@
{% extends 'layout.html' %}
{% block content %}
<div class="content-section">
<h1>Die Seite wird gerade überarbeitet</h1>
<h5>Gedult!</h5>
<p>Hier gibt es nichts zusehen!</p>
</div>
{% endblock content %}

View File

@@ -1,68 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css') }}">
{% if title %}
<title>NassiShneiderman Generator - {{ title }}</title>
{% else %}
<title>NassiShneiderman Generator</title>
{% endif %}
</head>
<body>
<header class="site-header">
<nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top">
<div class="container">
<a class="navbar-brand mr-4" href="/">NassiShneiderman Generator</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarToggle">
<div class="navbar-nav mr-auto">
<a class="nav-item nav-link" href="http://oleting.pythonanywhere.com/">Home</a>
<a class="nav-item nav-link" href="https://ole-siepmann.de/startseite/datenschutzerklaerung/">Datenschutz</a>
</div>
<!-- Navbar Right Side -->
<div class="navbar-nav">
</div>
</div>
</div>
</nav>
</header>
<main role="main" class="container">
<div class="row">
<div class="col-md-8">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">
{{message}}
</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</div>
</div>
</main>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

View File

@@ -1,61 +0,0 @@
{% extends 'layout.html' %}
{% block content %}
<div class="content-section">
{{ form.hidden_tag() }}
<div class="media">
<div class="media-body">
<p>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</p>
</div>
</div>
<form method='Post' action='' enctype="multipart/form-data">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<div class="form-group">
{{ form.comments.label() }}
{{ form.comments(class="form-control-file") }}
{% if form.comments.errors %}
{% for error in form.comments.errors %}
<span class="text-danger">{{ error }}</span></br>
{% endfor %}
{% endif %}
</div>
<div class="form-group">
{{ form.types.label() }}
{{ form.types(class="form-control-file") }}
{% if form.types.errors %}
{% for error in form.types.errors %}
<span class="text-danger">{{ error }}</span></br>
{% endfor %}
{% endif %}
</div>
<div class="form-group">
{{ form.remove_tags.label() }}
{{ form.remove_tags(class="form-control-file") }}
{% if form.remove_tags.errors %}
{% for error in form.remove_tags.errors %}
<span class="text-danger">{{ error }}</span></br>
{% endfor %}
{% endif %}
</div>
<legend class="border-bottom mb-4">.java Datei hochladen:</legend>
<div class="form-group">
{{ form.java.label() }}
{{ form.java(class="form-control-file") }}
{% if form.java.errors %}
{% for error in form.java.errors %}
<span class="text-danger">{{ error }}</span></br>
{% endfor %}
{% endif %}
</div>
<div class="form-group">
{{ form.submit(class="btn-outline-info") }}
</div>
</fieldset>
</form>
</div>
{% endblock content %}