Spaces:
Paused
Paused
Update app.py via AI Editor
Browse files
app.py
CHANGED
@@ -7,12 +7,14 @@ from io import BytesIO, StringIO
|
|
7 |
import dash
|
8 |
import dash_bootstrap_components as dbc
|
9 |
from dash import html, dcc, Input, Output, State, callback_context, MATCH, ALL
|
|
|
10 |
from docx.shared import Pt
|
11 |
from docx.enum.style import WD_STYLE_TYPE
|
12 |
from PyPDF2 import PdfReader
|
13 |
import openai
|
14 |
import logging
|
15 |
import threading
|
|
|
16 |
|
17 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
|
18 |
|
@@ -52,7 +54,6 @@ def get_right_col_content(selected_type):
|
|
52 |
type="dot",
|
53 |
children=[html.Div(id="loading-output")]
|
54 |
))
|
55 |
-
# Generate and Download buttons at the top
|
56 |
controls.append(
|
57 |
dbc.Row([
|
58 |
dbc.Col(
|
@@ -68,7 +69,6 @@ def get_right_col_content(selected_type):
|
|
68 |
)
|
69 |
controls.append(html.Hr())
|
70 |
controls.append(html.Div(id='document-preview', className="border p-3 mb-3"))
|
71 |
-
# Upload and radio only for non-shred
|
72 |
if selected_type != "Shred":
|
73 |
controls.append(html.Div([
|
74 |
html.Label(f"Upload {selected_type} Document"),
|
@@ -102,7 +102,6 @@ def get_right_col_content(selected_type):
|
|
102 |
return dbc.Card(dbc.CardBody(controls))
|
103 |
|
104 |
def get_left_col_content():
|
105 |
-
# Chat card under doc-type buttons
|
106 |
chat_card = dbc.Card(
|
107 |
dbc.CardBody([
|
108 |
html.H5("AI Chat", className="mb-2"),
|
@@ -334,7 +333,6 @@ def generate_any_doc(n_clicks_list, btn_ids, radio_values, upload_contents, uplo
|
|
334 |
doc_type = btn_ids[idx]['index']
|
335 |
document_type = doc_type
|
336 |
|
337 |
-
# SHRED CASE: Use uploaded_files directly, no radio or upload needed
|
338 |
if doc_type == "Shred":
|
339 |
if not uploaded_files:
|
340 |
logging.info("No uploaded files for Shred. Aborting.")
|
@@ -406,13 +404,13 @@ def generate_any_doc(n_clicks_list, btn_ids, radio_values, upload_contents, uplo
|
|
406 |
elif doc_type in ["Pink", "Red", "Gold"]:
|
407 |
generated = generate_document(doc_type, [doc_content])
|
408 |
current_document = generated
|
409 |
-
preview =
|
410 |
logging.info(f"{doc_type} document generated.")
|
411 |
return preview, f"{doc_type} generated"
|
412 |
else:
|
413 |
generated = generate_document(doc_type, [doc_content])
|
414 |
current_document = generated
|
415 |
-
preview =
|
416 |
logging.info(f"{doc_type} document generated.")
|
417 |
return preview, f"{doc_type} generated"
|
418 |
except Exception as e:
|
@@ -437,24 +435,41 @@ def update_uploaded_doc_name(contents, filename, id_dict):
|
|
437 |
def spreadsheet_preview(text, doc_type=None):
|
438 |
if doc_type is None:
|
439 |
doc_type = ""
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
458 |
|
459 |
def generate_document(document_type, file_contents):
|
460 |
if document_type in spreadsheet_types:
|
@@ -548,7 +563,7 @@ Now, provide the updated {selected_doc_type}:
|
|
548 |
if selected_doc_type in spreadsheet_types:
|
549 |
preview = spreadsheet_preview(current_document, selected_doc_type)
|
550 |
else:
|
551 |
-
preview =
|
552 |
return f"Document updated based on: {chat_input}", preview
|
553 |
except Exception as e:
|
554 |
logging.error(f"Error updating document via chat: {str(e)}")
|
@@ -579,8 +594,10 @@ def download_document(n_clicks, selected_doc_type):
|
|
579 |
return dcc.send_string(f"Error downloading {selected_doc_type}: {str(e)}", f"{selected_doc_type}_error.txt")
|
580 |
else:
|
581 |
try:
|
|
|
582 |
doc = Document()
|
583 |
-
|
|
|
584 |
output = BytesIO()
|
585 |
doc.save(output)
|
586 |
logging.info(f"{selected_doc_type} document downloaded as Word.")
|
|
|
7 |
import dash
|
8 |
import dash_bootstrap_components as dbc
|
9 |
from dash import html, dcc, Input, Output, State, callback_context, MATCH, ALL
|
10 |
+
from dash.dash_table import DataTable
|
11 |
from docx.shared import Pt
|
12 |
from docx.enum.style import WD_STYLE_TYPE
|
13 |
from PyPDF2 import PdfReader
|
14 |
import openai
|
15 |
import logging
|
16 |
import threading
|
17 |
+
import re
|
18 |
|
19 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
|
20 |
|
|
|
54 |
type="dot",
|
55 |
children=[html.Div(id="loading-output")]
|
56 |
))
|
|
|
57 |
controls.append(
|
58 |
dbc.Row([
|
59 |
dbc.Col(
|
|
|
69 |
)
|
70 |
controls.append(html.Hr())
|
71 |
controls.append(html.Div(id='document-preview', className="border p-3 mb-3"))
|
|
|
72 |
if selected_type != "Shred":
|
73 |
controls.append(html.Div([
|
74 |
html.Label(f"Upload {selected_type} Document"),
|
|
|
102 |
return dbc.Card(dbc.CardBody(controls))
|
103 |
|
104 |
def get_left_col_content():
|
|
|
105 |
chat_card = dbc.Card(
|
106 |
dbc.CardBody([
|
107 |
html.H5("AI Chat", className="mb-2"),
|
|
|
333 |
doc_type = btn_ids[idx]['index']
|
334 |
document_type = doc_type
|
335 |
|
|
|
336 |
if doc_type == "Shred":
|
337 |
if not uploaded_files:
|
338 |
logging.info("No uploaded files for Shred. Aborting.")
|
|
|
404 |
elif doc_type in ["Pink", "Red", "Gold"]:
|
405 |
generated = generate_document(doc_type, [doc_content])
|
406 |
current_document = generated
|
407 |
+
preview = narrative_preview(generated)
|
408 |
logging.info(f"{doc_type} document generated.")
|
409 |
return preview, f"{doc_type} generated"
|
410 |
else:
|
411 |
generated = generate_document(doc_type, [doc_content])
|
412 |
current_document = generated
|
413 |
+
preview = narrative_preview(generated)
|
414 |
logging.info(f"{doc_type} document generated.")
|
415 |
return preview, f"{doc_type} generated"
|
416 |
except Exception as e:
|
|
|
435 |
def spreadsheet_preview(text, doc_type=None):
|
436 |
if doc_type is None:
|
437 |
doc_type = ""
|
438 |
+
try:
|
439 |
+
df = pd.read_csv(StringIO(text))
|
440 |
+
table = DataTable(
|
441 |
+
columns=[{"name": i, "id": i} for i in df.columns],
|
442 |
+
data=df.to_dict('records'),
|
443 |
+
style_table={'overflowX': 'auto', 'maxHeight': '500px', 'overflowY': 'auto'},
|
444 |
+
style_cell={'textAlign': 'left', 'whiteSpace': 'normal', 'height': 'auto', 'minWidth': '120px', 'maxWidth': '320px'},
|
445 |
+
page_size=15
|
446 |
+
)
|
447 |
+
return html.Div(table)
|
448 |
+
except Exception as e:
|
449 |
+
logging.error(f"Error parsing CSV for preview: {str(e)}")
|
450 |
+
return html.Div([
|
451 |
+
html.Div("Unable to display spreadsheet preview. Raw output:", style={'fontWeight': 'bold'}),
|
452 |
+
html.Pre(text, style={'whiteSpace': 'pre-wrap', 'fontFamily': 'monospace'})
|
453 |
+
])
|
454 |
+
|
455 |
+
def narrative_preview(text):
|
456 |
+
plain = strip_markdown(text)
|
457 |
+
return html.Pre(plain, style={'whiteSpace': 'pre-wrap', 'fontFamily': 'sans-serif'})
|
458 |
+
|
459 |
+
def strip_markdown(text):
|
460 |
+
text = re.sub(r'(\*\*|__)(.*?)\1', r'\2', text)
|
461 |
+
text = re.sub(r'(\*|_)(.*?)\1', r'\2', text)
|
462 |
+
text = re.sub(r'`{1,3}[^`]*`{1,3}', '', text)
|
463 |
+
text = re.sub(r'^#+ ', '', text, flags=re.MULTILINE)
|
464 |
+
text = re.sub(r'^> ', '', text, flags=re.MULTILINE)
|
465 |
+
text = re.sub(r'!\[.*?\]\(.*?\)', '', text)
|
466 |
+
text = re.sub(r'\[([^\]]+)\]\([^)]+\)', r'\1', text)
|
467 |
+
text = re.sub(r'^\s*[-*+] ', '', text, flags=re.MULTILINE)
|
468 |
+
text = re.sub(r'^\s*\d+\.\s+', '', text, flags=re.MULTILINE)
|
469 |
+
text = text.replace('---', '')
|
470 |
+
text = text.replace('___', '')
|
471 |
+
text = text.replace('***', '')
|
472 |
+
return text.strip()
|
473 |
|
474 |
def generate_document(document_type, file_contents):
|
475 |
if document_type in spreadsheet_types:
|
|
|
563 |
if selected_doc_type in spreadsheet_types:
|
564 |
preview = spreadsheet_preview(current_document, selected_doc_type)
|
565 |
else:
|
566 |
+
preview = narrative_preview(current_document)
|
567 |
return f"Document updated based on: {chat_input}", preview
|
568 |
except Exception as e:
|
569 |
logging.error(f"Error updating document via chat: {str(e)}")
|
|
|
594 |
return dcc.send_string(f"Error downloading {selected_doc_type}: {str(e)}", f"{selected_doc_type}_error.txt")
|
595 |
else:
|
596 |
try:
|
597 |
+
plain = strip_markdown(current_document)
|
598 |
doc = Document()
|
599 |
+
for para in plain.split('\n'):
|
600 |
+
doc.add_paragraph(para)
|
601 |
output = BytesIO()
|
602 |
doc.save(output)
|
603 |
logging.info(f"{selected_doc_type} document downloaded as Word.")
|