Source code for solidipes.reports.widgets.display_file

import os
import urllib.parse

import streamlit as st

################################################################
from datasize import DataSize
from streamlit.components.v1 import html

from solidipes.loaders.file_sequence import FileSequence
from solidipes.loaders.group import loader_list as group_loader_list
from solidipes.loaders.mime_types import extension2mime_type, is_valid_extension, mime_types2extensions
from solidipes.loaders.pyvista_mesh import PyvistaMesh
from solidipes.loaders.sequence import Sequence
from solidipes.reports.widgets.utils import FileWrapper
from solidipes.utils import get_mimes, logging, set_mimes

from .solidipes_widget import SolidipesWidget as SPW

################################################################

print = logging.invalidPrint
logger = logging.getLogger()
################################################################


[docs] class DisplayFile(SPW): def __init__(self, filename: str, loader_name: str, paths_str: str, options_layout=None, **kwargs): super().__init__(**kwargs) self.fname = filename self.f = FileWrapper(self._load(filename, loader_name, paths_str)) self.f.state.valid = self.f.valid_loading title = self.get_file_title(self.f) st.markdown("<br>", unsafe_allow_html=True) with self.layout: with st.spinner("Loading... please wait"): st.markdown(title) self.show_file()
[docs] def _load(self, filename: str, loader_name: str, paths_str: str): from solidipes.loaders.file import load_file group_loader_dict = {loader.__name__: loader for loader in group_loader_list} if loader_name in group_loader_dict: dir_path = os.path.dirname(filename) encoded_paths = paths_str.split(",") paths = [urllib.parse.unquote(p) for p in encoded_paths] paths = [os.path.join(dir_path, p) for p in paths] loader = group_loader_dict[loader_name] return loader(pattern=filename, paths=paths) else: return load_file(filename)
[docs] def show_file(self): e = self.f if not e.state.valid and e.errors: for err in e.errors: st.error(err) st.sidebar.button( "&#8629; Back to file list", on_click=lambda: html("<script>window.parent.history.back();</script>"), use_container_width=True, type="primary", ) col1, col2, col3, col4, col5 = st.columns(5) self.show_discussions(e) if e.state.adding_comment: from streamlit_ace import st_ace content = st_ace( theme="textmate", show_gutter=False, key=f"chat_input_{e.unique_identifier}", ) if content: import re m = re.match(r"(\w+):(.*)", content) if m: e.add_message(m[1], m[2].strip()) else: e.add_message("Unknown", content) e.state.adding_comment = False st.rerun() if isinstance(e.f, Sequence) and not (isinstance(e.f, FileSequence) and e.sequence_type == PyvistaMesh): sequence_switcher = st.container() with sequence_switcher: st.write(f"Sequence of {e._element_count} elements.") selected_element = st.slider( "Current element", min_value=1, max_value=e._element_count, step=1, key="sequence_switcher_" + e.unique_identifier, ) e.select_element(selected_element - 1, False) file_size = e.file_info.size col4.download_button( f"Download {os.path.basename(e.file_info.path)} ({DataSize(file_size):.2a})", data=open(e.file_info.path, "rb"), file_name=os.path.basename(e.file_info.path), key="download_" + e.unique_identifier, ) try: _link = self._get_jupyter_link() _link += "/" + os.path.dirname(e.file_info.path) col2.markdown( f"[Edit in Jupyterlab]({_link}/)", unsafe_allow_html=True, ) _link = self._get_filebrowser_link() _link += "/" + os.path.dirname(e.file_info.path) col2.markdown( f"[Edit in Filebrowser]({_link}/)", unsafe_allow_html=True, ) except RuntimeError: pass col3.button( ":speech_balloon: add a comment", on_click=lambda: setattr(e.state, "adding_comment", True), key=f"add_comment_button_{e.unique_identifier}", ) self.mime_type_information(e, col1, st.container()) container_error = st.container() with st.container(): try: with st.spinner(f"Loading {e.file_info.path}..."): e.view() except Exception as err: with container_error.expander(":warning: Error trying to display file"): st.exception(err) logger.error("Error trying to display file") logger.error(err)
# raise err
[docs] def show_discussions(self, e): from solidipes.reports.widgets.custom_widgets import SpeechBubble if not e.discussions: return if e.archived_discussions: st.button("Unarchive messages", on_click=e.archive_discussions(False)) else: st.markdown("### :speech_balloon: Discussions") for author, message in e.discussions: SpeechBubble(author, message) st.markdown("<br>", unsafe_allow_html=True) st.button( "Respond", on_click=lambda: setattr(e.state, "adding_comment", True), key=f"respond_button_{e.unique_identifier}", ) st.button("Mark as resolved", on_click=e.archive_discussions()) st.markdown("---")
[docs] def mime_type_information(self, e, layout, main_layout): valid_ext = is_valid_extension(e.file_info.path, e.file_info.type) if not e.state.valid and not valid_ext: type_choice_box = layout.empty() type_choice = type_choice_box.container() sel = type_choice.radio( "Type selection", options=["extension", "mime"], key="type_sel_" + e.unique_identifier, horizontal=True, ) choice = None if sel == "mime": possible_types = [e for e in mime_types2extensions.keys()] choice = type_choice.selectbox( "type", ["Select type"] + possible_types, key="mime_" + e.unique_identifier, ) else: def format_types(x): if x == "Select type": return x return f"{x} ({extension2mime_type[x][0]})" possible_types = [e for e in extension2mime_type.keys()] choice = type_choice.selectbox( "extension", ["Select type"] + possible_types, format_func=format_types, key="mime_" + e.unique_identifier, ) if choice != "Select type": choice = extension2mime_type[choice][0] if choice != "Select type": st.write(choice) confirm = main_layout.button( f"Confirm change type {choice} -> {mime_types2extensions[choice]}", type="primary", use_container_width=True, ) if confirm: mimes = get_mimes() mimes[e.file_info.path] = choice set_mimes(mimes) e.clear_cached_metadata(["file_info", "valid_loading"]) st.rerun() else: layout.info(e.file_info.type)
[docs] def get_file_title(self, e): path = e.file_info.path if isinstance(e.f, FileSequence): path = e.f.path file_title = f"{path}" if isinstance(e.f, FileSequence): file_size = e.total_size else: file_size = e.file_info.size file_title += f"&nbsp; &nbsp; **{e.file_info.type.strip()}/{DataSize(file_size):.2a}** " title = file_title if e.state.valid and (not e.discussions or e.archived_discussions): title = ":white_check_mark: &nbsp; &nbsp;" + file_title else: title = ":no_entry_sign: &nbsp; &nbsp; " + file_title # if e.discussions or e.state.view: # title += "&nbsp; :arrow_forward: &nbsp; &nbsp; " if e.state.view: title += "&nbsp; :open_book:" if e.discussions: title += "&nbsp;:e-mail: &nbsp; :arrow_forward: **You have a message**" return title