-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstreamlit_app.py
159 lines (130 loc) · 6.22 KB
/
streamlit_app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import streamlit as st
import os
import base64
import logging
import traceback
from libs.decompile import decompile_qvm
from libs.convert import convert_qvm
def initialize_session_state():
if "file" not in st.session_state:
st.session_state.file = None
if "operation" not in st.session_state:
st.session_state.operation = None
if "version" not in st.session_state:
st.session_state.version = None
if "code" not in st.session_state:
st.session_state.code = None
if "output_file" not in st.session_state:
st.session_state.output_file = None
if "download_link" not in st.session_state:
st.session_state.download_link = None
import os
def clear_resources(directory):
# Check if the directory exists
if not os.path.exists(directory):
# Create the directory if it does not exist
os.makedirs(directory)
else:
# If the directory exists, remove all files within it
for file in os.listdir(directory):
file_path = os.path.join(directory, file)
# Check if it's a file and not a directory before removing
if os.path.isfile(file_path):
os.remove(file_path)
def generate_download_link(data=None, filename="download.txt", file_extension="text/plain", auto_click=False):
try:
# Check for empty file name
if not filename or len(filename) == 0:
st.toast("Please enter a valid file name.", icon="❌")
logging.error("Error in code downloading: Please enter a valid file name.")
return
# Check for empty data
if data is None:
st.toast("Data is empty. Cannot download an empty file.", icon="❌")
logging.error("Error in code downloading: Data is empty.")
return
# Get the file extension if not provided
if not file_extension or len(file_extension) == 0:
file_extension = filename.split(".")[-1]
logging.info(f"Downloading code to file: {filename} with extension: {file_extension}")
# Check if data is binary or text
try:
if isinstance(data, bytes):
# Data is binary, no need to encode it as utf-8
b64_data = base64.b64encode(data).decode()
else:
# Data is text, encode it as utf-8 before base64 encoding
b64_data = base64.b64encode(data.encode('utf-8')).decode()
except Exception:
logging.error(f"Error in encoding data: {traceback.format_exc()}")
href = f"data:{file_extension};base64,{b64_data}" # creating the href for anchor tag
link = f'<a id="download_link" href="{href}" download="{filename}">Download Code</a>' # creating the anchor tag
# JavaScript code to automatically click the link
auto_click_js = "<script>document.getElementById('download_link').click();</script>"
if auto_click:
st.components.v1.html(link + auto_click_js, height=0, scrolling=False)
else:
return link # return the anchor tag
except Exception as e:
st.toast(traceback.format_exc())
logging.error(f"Error in code downloading: {traceback.format_exc()}")
def main():
st.title("Project IGI Compiler - HM")
initialize_session_state()
clear_resources('input')
clear_resources('output')
uploaded_file = st.file_uploader("Choose a file", type=['qvm'])
if uploaded_file is not None:
with open(os.path.join('input', uploaded_file.name), 'wb') as file:
file.write(uploaded_file.getvalue())
st.session_state.file = uploaded_file.name
with st.form(key='conversion_form'):
col1, col2,_,col3, col4 = st.columns([2, 2, 1, 2, 2],gap='small')
with col1:
convert_clicked = st.form_submit_button('Convert')
with col2:
# Use a placeholder to center the number input
with st.container():
st.session_state.version = st.number_input('Version', min_value=5, max_value=7, step=2,label_visibility='collapsed')
with col3:
decompile_clicked = st.form_submit_button('Decompile')
with col4:
download_clicked = st.form_submit_button('Download')
# Conversion process
if convert_clicked and st.session_state.file is not None:
try:
st.session_state.output_file = convert_qvm(st.session_state.version)
with open(st.session_state.output_file, 'rb') as file:
convert_data = file.read()
st.session_state.download_link = generate_download_link(convert_data, filename=st.session_state.output_file, auto_click=True)
except Exception as e:
st.error(f"An error occurred during conversion: {e}")
logging.error(f"Conversion error: {traceback.format_exc()}")
# Decompile process
if decompile_clicked and st.session_state.file is not None:
try:
st.session_state.output_file = decompile_qvm()
with open(st.session_state.output_file, 'r') as file:
st.session_state.code = file.read()
except Exception as e:
st.error(f"An error occurred during decompiling: {e}")
logging.error(f"Decompilation error: {traceback.format_exc()}")
# Download process
if download_clicked and st.session_state.code is not None:
try:
st.session_state.download_link = generate_download_link(st.session_state.code, filename=st.session_state.output_file, auto_click=True)
except Exception as e:
st.error(f"An error occurred during download: {e}")
logging.error(f"Download error: {traceback.format_exc()}")
# Display the output code or conversion success message
if st.session_state.code is not None:
st.code(st.session_state.code, language='cpp')
if st.session_state.output_file is not None:
if "qvm" in st.session_state.output_file:
st.success("File converted successfully.")
if __name__ == "__main__":
try:
main()
except Exception as e:
st.error(f'An error occurred: {e}')
logging.error(f"Main function error: {traceback.format_exc()}")