Приложение Dash требует удаления загруженных файлов Excel из папки загрузок.Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Приложение Dash требует удаления загруженных файлов Excel из папки загрузок.

Сообщение Anonymous »

Идея состоит в том, что можно загружать и отображать несколько файлов Excel, а также есть возможность удалить каждый файл из просмотра и папки загрузок.
Не удается удалить файл. Вот код с ошибкой «Имя файла — нет, удаление отсутствует». Кнопка удаления активна и пытается удалить файл, но в конечном итоге терпит неудачу.
import os
from dash import dcc, html, dash_table, Input, Output, State, callback, callback_context
from dash.dependencies import ALL
import dash_bootstrap_components as dbc
import base64
import datetime
import io
import pandas as pd

# Import file management functions
from constants.index import table_style, cell_style, header_style

from components.image_component import create_image

# Fetch upload icons
upload_icon = "assets/images/icons/upload-colored-icon.png"
download_icon = "assets/images/icons/download-icon.png"

# Upload directory
upload_directory = "uploaded_files"

# Ensure the upload directory exists
if not os.path.exists(upload_directory):
os.makedirs(upload_directory)

# Define custom loader styles
loader_style = {
"position": "fixed",
"top": "0",
"left": "0",
"width": "100%",
"height": "100%",
"backgroundColor": "rgba(255, 255, 255, 0.8)", # Semi-transparent background
"display": "flex",
"justifyContent": "center",
"alignItems": "center",
"zIndex": "9999", # Ensure it's on top of everything
}

def file_uploader():
return html.Div(
[
dcc.Upload(
id="upload-data",
children=dbc.Button(
className="upload-button",
id="upload-button",
children=[
create_image(image_path=upload_icon, image_style="icon"),
html.Span("Upload Files"),
],
),
multiple=True,
),
dbc.Alert("The uploaded files should follow predefined formats.", className="upload-alert"),
dcc.Loading(
id="loading-spinner",
type="circle",
fullscreen=True,
style=loader_style,
children=html.Div(id="output-data-upload"),
),
]
)

def save_file(contents, filename):
"""Save the uploaded file to the server."""
content_type, content_string = contents.split(",")
decoded = base64.b64decode(content_string)

# Create the full path for the file
file_path = os.path.join(upload_directory, filename)

# Write the file based on its type
try:
with open(file_path, "wb") as f:
f.write(decoded)
except Exception as e:
print(f"Error saving file {filename}: {e}")
return html.Div([f"There was an error saving the file: {e}"])

return file_path # Return the path of the saved file

def load_saved_files():
"""Load and display saved files from the server."""
saved_files = []
for filename in os.listdir(upload_directory):
file_path = os.path.join(upload_directory, filename)

# Display each saved file
if filename.endswith(".csv"):
df = pd.read_csv(file_path)
elif filename.endswith(".xls") or filename.endswith(".xlsx"):
df = pd.read_excel(file_path)
else:
continue

saved_files.append(
html.Div(
[
html.Div(
className="flex",
children=[
html.H5(filename),
dbc.Button(
"Delete",
id={"type": "delete-button", "index": filename},
color="danger",
n_clicks=0,
),
],
),
dash_table.DataTable(
df.to_dict("records"), [{"name": i, "id": i} for i in df.columns],
page_size=10,
style_table=table_style,
style_cell=cell_style,
style_header=header_style,
fixed_rows={"headers": True},
),
html.Hr(),
]
)
)
return saved_files

def parse_contents(contents, filename, date):
"""Save and parse the uploaded file."""
# Save the file to the server and get its path
file_path = save_file(contents, filename)

decoded = base64.b64decode(contents.split(",")[1])
try:
if filename.endswith(".csv"):
df = pd.read_csv(io.StringIO(decoded.decode("utf-8")))
elif filename.endswith(".xls") or filename.endswith(".xlsx"):
df = pd.read_excel(io.BytesIO(decoded))
except Exception as e:
print(e)
return html.Div(["There was an error processing this file."])

return html.Div(
[
html.Div(
className="flex",
children=[
html.H5(filename),
html.Div(f"File {filename} saved successfully at {file_path}."),
],
),
html.H6(datetime.datetime.fromtimestamp(date)),
dash_table.DataTable(
df.to_dict("records"),
[{"name": i, "id": i} for i in df.columns],
page_size=10,
style_table=table_style,
style_cell=cell_style,
style_header=header_style,
fixed_rows={"headers": True},
),
html.Hr(),
html.Div("Raw Content"),
html.Pre(
contents[0:200] + "...",
style={"whiteSpace": "pre-wrap", "wordBreak": "break-all"},
),
]
)

def delete_file(filename):
"""Delete the selected file from the upload directory."""
file_path = os.path.join(upload_directory, filename)
if os.path.exists(file_path):
os.remove(file_path)
print(f"File {filename} deleted.")
else:
print(f"File {filename} not found.")

@callback(
Output("output-data-upload", "children"),
Input("upload-data", "contents"),
State("upload-data", "filename"),
State("upload-data", "last_modified"),
Input({"type": "delete-button", "index": ALL}, "n_clicks"),
State({"type": "delete-button", "index": ALL}, "index"),
)
def update_output(list_of_contents, list_of_names, list_of_dates, delete_clicks, delete_filenames):
ctx = callback_context
triggered = ctx.triggered

# Handle file deletion
if triggered and "delete-button" in triggered[0]["prop_id"]:
for i, n_clicks in enumerate(delete_clicks):
if n_clicks > 0:
filename_to_delete = delete_filenames

# Debugging: Ensure filename is passed
if filename_to_delete is not None:
print(f"Attempting to delete file: {filename_to_delete}")
delete_file(filename_to_delete)
else:
print("Filename is None, skipping deletion")
break # Ensure we only delete one file per click

# Display saved files or newly uploaded files
if list_of_contents is not None:
children = [parse_contents(c, n, d) for c, n, d in zip(list_of_contents, list_of_names, list_of_dates)]
return children
else:
return load_saved_files()



Подробнее здесь: https://stackoverflow.com/questions/790 ... loads-fold
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»