bluenevus commited on
Commit
677c25b
·
1 Parent(s): a74f448

Update app.py via AI Editor

Browse files
Files changed (1) hide show
  1. app.py +76 -15
app.py CHANGED
@@ -12,18 +12,14 @@ import PyPDF2
12
  import docx
13
  import chardet
14
 
15
- # Initialize the Dash app
16
  app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
17
 
18
- # Get OpenAI API key from Hugging Face Spaces environment variable
19
  openai.api_key = os.environ.get('OPENAI_API_KEY')
20
 
21
- # Global variables
22
  uploaded_files = {}
23
  current_matrix = None
24
  matrix_type = None
25
 
26
- # Matrix types and their descriptions
27
  matrix_types = {
28
  "Project Deliverables Matrix": "Generate a project deliverables matrix all presumed and actual deliverables based on tasks, requirements and scope.",
29
  "Communications Plan Matrix": "Create a matrix showing stakeholders, communication methods, frequency, and responsibilities.",
@@ -79,7 +75,7 @@ app.layout = dbc.Container([
79
  ])
80
  ], width=3),
81
  dbc.Col([
82
- html.Div(style={"height": "20px"}), # Added small gap
83
  dcc.Loading(
84
  id="loading-indicator",
85
  type="dot",
@@ -89,7 +85,7 @@ app.layout = dbc.Container([
89
  dbc.Button("Download Matrix", id="btn-download", color="success", className="mt-3"),
90
  dcc.Download(id="download-matrix"),
91
  html.Hr(),
92
- html.Div(style={"height": "20px"}), # Added small gap
93
  dcc.Loading(
94
  id="chat-loading",
95
  type="dot",
@@ -124,6 +120,12 @@ def parse_file_content(contents, filename):
124
  print(f"Error processing file {filename}: {str(e)}")
125
  return "Error processing file"
126
 
 
 
 
 
 
 
127
  @app.callback(
128
  Output('file-list', 'children'),
129
  Input('upload-files', 'contents'),
@@ -137,10 +139,47 @@ def update_output(list_of_contents, list_of_names, existing_files):
137
  for i, (content, name) in enumerate(zip(list_of_contents, list_of_names)):
138
  file_content = parse_file_content(content, name)
139
  uploaded_files[name] = file_content
140
- new_files.append(html.Div([
141
- html.Button('×', id={'type': 'remove-file', 'index': name}, style={'marginRight': '5px', 'fontSize': '10px'}),
142
- html.Span(name)
143
- ]))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  if existing_files is None:
145
  existing_files = []
146
  return existing_files + new_files
@@ -157,9 +196,32 @@ def remove_file(n_clicks, existing_files):
157
  ctx = dash.callback_context
158
  if not ctx.triggered:
159
  raise PreventUpdate
160
- removed_file = ctx.triggered[0]['prop_id'].split(',')[0].split(':')[-1].strip('}')
 
 
 
 
 
 
 
 
 
161
  uploaded_files.pop(removed_file, None)
162
- return [file for file in existing_files if file['props']['children'][1]['props']['children'] != removed_file]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
 
164
  def generate_matrix_with_gpt(matrix_type, file_contents):
165
  prompt = f"""Generate a {matrix_type} based on the following project artifacts:
@@ -188,7 +250,7 @@ Now, generate the {matrix_type}:
188
  )
189
 
190
  matrix_text = response.choices[0].message.content.strip()
191
- print("Raw matrix text from GPT:", matrix_text) # For debugging
192
 
193
  lines = [line.strip() for line in matrix_text.split('\n') if '|' in line]
194
  data = [line.split('|') for line in lines]
@@ -260,7 +322,7 @@ Now, provide the updated {matrix_type}:
260
  )
261
 
262
  updated_matrix_text = response.choices[0].message.content.strip()
263
- print("Raw updated matrix text from GPT:", updated_matrix_text) # For debugging
264
 
265
  lines = [line.strip() for line in updated_matrix_text.split('\n') if '|' in line]
266
  data = [line.split('|') for line in lines]
@@ -283,7 +345,6 @@ def download_matrix(n_clicks):
283
  if current_matrix is None:
284
  raise PreventUpdate
285
 
286
- # Create an in-memory Excel file
287
  output = io.BytesIO()
288
  with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
289
  current_matrix.to_excel(writer, sheet_name='Sheet1', index=False)
 
12
  import docx
13
  import chardet
14
 
 
15
  app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
16
 
 
17
  openai.api_key = os.environ.get('OPENAI_API_KEY')
18
 
 
19
  uploaded_files = {}
20
  current_matrix = None
21
  matrix_type = None
22
 
 
23
  matrix_types = {
24
  "Project Deliverables Matrix": "Generate a project deliverables matrix all presumed and actual deliverables based on tasks, requirements and scope.",
25
  "Communications Plan Matrix": "Create a matrix showing stakeholders, communication methods, frequency, and responsibilities.",
 
75
  ])
76
  ], width=3),
77
  dbc.Col([
78
+ html.Div(style={"height": "20px"}),
79
  dcc.Loading(
80
  id="loading-indicator",
81
  type="dot",
 
85
  dbc.Button("Download Matrix", id="btn-download", color="success", className="mt-3"),
86
  dcc.Download(id="download-matrix"),
87
  html.Hr(),
88
+ html.Div(style={"height": "20px"}),
89
  dcc.Loading(
90
  id="chat-loading",
91
  type="dot",
 
120
  print(f"Error processing file {filename}: {str(e)}")
121
  return "Error processing file"
122
 
123
+ def truncate_filename(filename, max_length=24):
124
+ if len(filename) <= max_length:
125
+ return filename
126
+ else:
127
+ return filename[:max_length - 3] + '...'
128
+
129
  @app.callback(
130
  Output('file-list', 'children'),
131
  Input('upload-files', 'contents'),
 
139
  for i, (content, name) in enumerate(zip(list_of_contents, list_of_names)):
140
  file_content = parse_file_content(content, name)
141
  uploaded_files[name] = file_content
142
+ new_files.append(
143
+ dbc.Card(
144
+ dbc.CardBody(
145
+ dbc.Row([
146
+ dbc.Col(
147
+ html.Span(
148
+ truncate_filename(name),
149
+ title=name,
150
+ style={
151
+ 'display': 'inline-block',
152
+ 'overflow': 'hidden',
153
+ 'textOverflow': 'ellipsis',
154
+ 'whiteSpace': 'nowrap',
155
+ 'maxWidth': '90%',
156
+ 'verticalAlign': 'middle',
157
+ }
158
+ ),
159
+ width='auto',
160
+ style={'display': 'flex', 'alignItems': 'center', 'padding': '0'}
161
+ ),
162
+ dbc.Col(
163
+ dbc.Button(
164
+ "Delete",
165
+ id={'type': 'remove-file', 'index': name},
166
+ color="danger",
167
+ size="sm",
168
+ style={'marginLeft': 'auto', 'float': 'right'}
169
+ ),
170
+ width='auto',
171
+ style={'display': 'flex', 'alignItems': 'center', 'justifyContent': 'flex-end', 'padding': '0'}
172
+ ),
173
+ ],
174
+ justify="between",
175
+ align="center",
176
+ style={"margin": "0", "padding": "0"}
177
+ ),
178
+ style={'padding': '6px 8px', 'margin': '0', 'display': 'flex', 'alignItems': 'center', 'background': 'none', 'boxShadow': 'none'}
179
+ ),
180
+ style={'border': 'none', 'boxShadow': 'none', 'background': 'none', 'marginBottom': '2px'}
181
+ )
182
+ )
183
  if existing_files is None:
184
  existing_files = []
185
  return existing_files + new_files
 
196
  ctx = dash.callback_context
197
  if not ctx.triggered:
198
  raise PreventUpdate
199
+ # Find which button was pressed
200
+ triggered_id = ctx.triggered[0]['prop_id'].split('.')[0]
201
+ # triggered_id is a dict-like string, e.g. "{'type':'remove-file','index':'filename'}"
202
+ # Safely eval to dict (since dash handles this)
203
+ import ast
204
+ try:
205
+ triggered_id_dict = ast.literal_eval(triggered_id)
206
+ removed_file = triggered_id_dict['index']
207
+ except Exception:
208
+ raise PreventUpdate
209
  uploaded_files.pop(removed_file, None)
210
+ # Filter out the file that was removed
211
+ filtered_files = []
212
+ for file_card in existing_files:
213
+ # file_card is a dict representing a dbc.Card
214
+ # Traverse to get filename from card body
215
+ try:
216
+ # Card > CardBody > Row > [Col, Col] > Col[0] > Span
217
+ filename_span = file_card['props']['children']['props']['children'][0]['props']['children'][0]['props']['children']
218
+ # The span text is truncated; check its title for the full name
219
+ span_title = file_card['props']['children']['props']['children'][0]['props']['children'][0]['props']['title']
220
+ if span_title != removed_file:
221
+ filtered_files.append(file_card)
222
+ except Exception:
223
+ filtered_files.append(file_card)
224
+ return filtered_files
225
 
226
  def generate_matrix_with_gpt(matrix_type, file_contents):
227
  prompt = f"""Generate a {matrix_type} based on the following project artifacts:
 
250
  )
251
 
252
  matrix_text = response.choices[0].message.content.strip()
253
+ print("Raw matrix text from GPT:", matrix_text)
254
 
255
  lines = [line.strip() for line in matrix_text.split('\n') if '|' in line]
256
  data = [line.split('|') for line in lines]
 
322
  )
323
 
324
  updated_matrix_text = response.choices[0].message.content.strip()
325
+ print("Raw updated matrix text from GPT:", updated_matrix_text)
326
 
327
  lines = [line.strip() for line in updated_matrix_text.split('\n') if '|' in line]
328
  data = [line.split('|') for line in lines]
 
345
  if current_matrix is None:
346
  raise PreventUpdate
347
 
 
348
  output = io.BytesIO()
349
  with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
350
  current_matrix.to_excel(writer, sheet_name='Sheet1', index=False)