Skip to content

Commit

Permalink
Update demo app with latest development changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
hreikin committed Mar 13, 2023
1 parent 958a047 commit 4aa8348
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 72 deletions.
5 changes: 2 additions & 3 deletions Home.py
Expand Up @@ -6,7 +6,6 @@
# Configure page title, layout, menu items and links.
st.set_page_config(
page_title="Streamlit Uploads Library",
initial_sidebar_state="expanded",
layout="wide",
menu_items={
"Get Help": "https://github.com/hreikin/streamlit-uploads-library",
Expand Down Expand Up @@ -53,5 +52,5 @@
default_uploader = UploadFiles(save_location="assets") # Wraps st.file_uploader and provides save functionality
"""
)
default_library = Library(directory="assets")
default_gallery = Gallery(directory="assets")
default_library = Library(directory="assets/landscape/")
default_gallery = Gallery(directory="assets/portrait/")
5 changes: 2 additions & 3 deletions pages/Caching.py
Expand Up @@ -5,7 +5,6 @@
# Configure page title, layout, menu items and links.
st.set_page_config(
page_title="Streamlit Uploads Library",
initial_sidebar_state="expanded",
layout="wide",
menu_items={
"Get Help": "https://github.com/hreikin/streamlit-uploads-library",
Expand All @@ -30,5 +29,5 @@
the `st.cache_resource.clear()` function provided by Streamlit.
"""
)
default_library = Library(directory="assets")
default_gallery = Gallery(directory="assets")
default_library = Library(directory="assets/landscape/")
default_gallery = Gallery(directory="assets/portrait/")
46 changes: 30 additions & 16 deletions pages/Gallery.py
Expand Up @@ -4,7 +4,6 @@
# Configure page title, layout, menu items and links.
st.set_page_config(
page_title="Streamlit Uploads Library",
initial_sidebar_state="expanded",
layout="wide",
menu_items={
"Get Help": "https://github.com/hreikin/streamlit-uploads-library",
Expand Down Expand Up @@ -39,39 +38,53 @@ class Gallery(Library):
Args:
directory (str): A str() of the path to the folder containing the gallery images, for example, "assets".
file_extensions (tuple): A tuple() containing strings of the file extensions to include in the gallery, default is (".png", ".jpg", ".jpeg").
image_alignment (str): A str() with the CSS keyword used to align the images and details columns.
number_of_columns (int): An int() defining the number of required columns, default is 5.
show_details (bool): A bool() to show or hide the file and edit details, True shows them, default is False to hide them and create a gallery.
uid (str): A str() containing a unique identifier allowing you to create multiple galleries on the same page containing the same images.
"""
def __init__(self, directory, file_extensions=(".png", ".jpg", ".jpeg"), number_of_columns=5, uid="gallery"):
image_alignment = "center"
show_details=False
super(Gallery, self).__init__(directory, file_extensions, image_alignment, number_of_columns, show_details, uid)
def fetch_files(self):
"""Returns a list of all files and filenames.
Returns a list of files and a list of filenames to be used by create_gallery().
def __init__(self, directory, file_extensions=(".png", ".jpg", ".jpeg"), image_alignment="center", number_of_columns=5, show_details=False, uid="gallery"):
self.directory = directory
self.file_extensions = file_extensions
self.image_alignment = image_alignment
self.number_of_columns = number_of_columns
self.show_details = show_details
self.uid = uid
super(Gallery, self).__init__(self.directory, self.file_extensions, self.image_alignment, self.number_of_columns, self.show_details, self.uid)
def fetch_files(self, directory, file_extensions):
"""Returns a list of all files.
Returns a list of files to be used by create_gallery().
Args:
directory (str): A str() of the path to the folder containing the gallery images, for example, "assets".
file_extensions (tuple): A tuple() containing strings of the file extensions to include in the library, default is (".png", ".jpg", ".jpeg").
Returns:
all_files (list): A list of files.
all_filenames (list): A list of filenames.
"""
return super().fetch_files()
return super().fetch_files(directory, file_extensions)
@st.cache_resource(experimental_allow_widgets=True, show_spinner="Refreshing gallery...")
def create_gallery(_self):
def create_gallery(_self, directory, file_extensions, image_alignment, number_of_columns, show_details, uid):
"""Creates a simple gallery with columns.
Creates a gallery using columns out of streamlit widgets.
Args:
directory (str): A str() of the path to the folder containing the gallery images, for example, "assets".
file_extensions (tuple): A tuple() containing strings of the file extensions to include in the gallery, default is (".png", ".jpg", ".jpeg").
image_alignment (str): A str() with the CSS keyword used to align the images and details columns.
number_of_columns (int): An int() indicating the number of columns to create.
show_details (bool): A bool() that when set to True allows the creation of libraries, default is False to create a gallery.
uid (str): A str() containing a unique identifier allowing you to create multiple libraries on the same page containing the same images.
Returns:
library_container (st.container): A streamlit widget containing the library.
library_gallery_container (st.container): A streamlit widget containing the gallery.
"""
return super().create_library(_self.number_of_columns, _self.show_details)
return super().create_library(directory, file_extensions, image_alignment, number_of_columns, show_details, uid)
'''

with st.sidebar:
Expand Down Expand Up @@ -99,8 +112,9 @@ def create_gallery(_self):
columns_gallery = Gallery(directory="assets", number_of_columns=4, uid="columns")
"""
)
default_gallery = Gallery(directory="assets")
columns_gallery = Gallery(directory="assets", number_of_columns=4, uid="columns")
default_gallery = Gallery(directory="assets/landscape/")
columns_gallery = Gallery(directory="assets/portrait/", number_of_columns=4, uid="gallery-columns")
mixed_gallery = Gallery(directory="assets/mixed/", uid="mixed-gallery")

with st.expander(label="**Source Code**", expanded=True):
st.code(body=source_code)
104 changes: 55 additions & 49 deletions pages/Library.py
Expand Up @@ -4,7 +4,6 @@
# Configure page title, layout, menu items and links.
st.set_page_config(
page_title="Streamlit Uploads Library",
initial_sidebar_state="expanded",
layout="wide",
menu_items={
"Get Help": "https://github.com/hreikin/streamlit-uploads-library",
Expand Down Expand Up @@ -56,24 +55,26 @@ def __init__(self, directory, file_extensions=(".png", ".jpg", ".jpeg"), image_a
self.number_of_columns = number_of_columns
self.show_details = show_details
self.uid = uid
self.library = self.create_library(self.number_of_columns, self.show_details)
self.library = self.create_library(self.directory, self.file_extensions, self.image_alignment, self.number_of_columns, self.show_details, self.uid)
def fetch_files(self):
"""Returns a list of all files and filenames.
def fetch_files(self, directory, file_extensions):
"""Returns a list of all files.
Returns a list of files and a list of filenames to be used by create_library().
Returns a list of files to be used by create_library().
Args:
directory (str): A str() of the path to the folder containing the library images, for example, "assets".
file_extensions (tuple): A tuple() containing strings of the file extensions to include in the library, default is (".png", ".jpg", ".jpeg").
Returns:
all_files (list): A list of files.
all_filenames (list): A list of filenames.
"""
self.all_files = list()
self.all_filenames = list()
for item in self.directory.rglob("*"):
if item.is_file() and item.name.endswith(self.file_extensions):
self.all_files.append(str(item.resolve()))
self.all_filenames.append(str(item.name))
return self.all_files, self.all_filenames
all_files = list()
for item in directory.rglob("*"):
if item.is_file() and item.name.endswith(file_extensions):
all_files.append(str(item.resolve()))
return all_files
def update_file(self, old_file, new_file, del_check=False):
"""Update or delete the file.
Expand All @@ -99,54 +100,58 @@ def update_file(self, old_file, new_file, del_check=False):
st.experimental_rerun()
@st.cache_resource(experimental_allow_widgets=True, show_spinner="Refreshing library...")
def create_library(_self, number_of_columns, show_details):
def create_library(_self, directory, file_extensions, image_alignment, number_of_columns, show_details, uid):
"""Creates a simple library with columns.
Creates a library using columns out of streamlit widgets.
Args:
number_of_columns (int): An int() indicating the number of columns to create.
show_details (bool): A bool() that when set to False allows the creation of galleries, default is True to create a library.
directory (str): A str() of the path to the folder containing the library images, for example, "assets".
file_extensions (tuple): A tuple() containing strings of the file extensions to include in the library, default is (".png", ".jpg", ".jpeg").
image_alignment (str): A str() with the CSS keyword used to align the images and details columns.
number_of_columns (int): An int() defining the number of required columns, default is 5.
show_details (bool): A bool() to show or hide the file and edit details, False hides them, default is True to show them.
uid (str): A str() containing a unique identifier allowing you to create multiple libraries on the same page containing the same images.
Returns:
library_container (st.container): A streamlit widget containing the library.
library_gallery_container (st.container): A streamlit widget containing the library.
"""
_self.library_container = st.container()
with _self.library_container:
library_gallery_container = st.container()
with library_gallery_container:
# To be able to display the images, details and buttons all in one row and aligned
# correctly so that images of different sizes don't affect the alignment of the details
# and buttons we need do some minor maths and keep track of multiple index values.
# First we instantiate some defaults.
_self.col_idx = 0
_self.filename_idx = 0
_self.max_idx = number_of_columns-1
col_idx = 0
filename_idx = 0
max_idx = number_of_columns-1
# Get the file list and filename list, work out the total number of files from the
# length of the file list.
_self.library_files, _self.library_filenames = _self.fetch_files()
_self.num_of_files = len(_self.library_files)
library_files = _self.fetch_files(directory, file_extensions)
num_of_files = len(library_files)
# Work out the number of rows required by dividing the number of files by the number of
# columns and rounding up using `math.ceil`.
_self.num_of_rows_req = ceil(_self.num_of_files / number_of_columns)
num_of_rows_req = ceil(num_of_files / number_of_columns)
# Create the required number of rows (st.container).
_self.library_rows = list()
_self.library_rows_idx = 0
for i in range(_self.num_of_rows_req):
_self.library_rows.append(st.container())
library_rows = list()
library_rows_idx = 0
for i in range(num_of_rows_req):
library_rows.append(st.container())
# For each library row we need to create separate rows (st.container) for images,
# and rows (st.expander) for details and buttons to keep them in the correct columns.
for idx in range(_self.num_of_rows_req):
with _self.library_rows[_self.library_rows_idx]:
_self.imgs_columns = list(st.columns(number_of_columns))
for idx in range(num_of_rows_req):
with library_rows[library_rows_idx]:
imgs_columns = list(st.columns(number_of_columns))
# Since we are keeping track of the column and filename indexes we can use
# those to slice the `library_files` list at the correct points for each row
# and then increase or reset the indexes as required.
for img in _self.library_files[_self.filename_idx:(_self.filename_idx + number_of_columns)]:
with _self.imgs_columns[_self.col_idx]:
for img in library_files[filename_idx:(filename_idx + number_of_columns)]:
with imgs_columns[col_idx]:
st.image(img, use_column_width="auto")
st.write(
f"""<style>
[data-testid="stHorizontalBlock"] {{
align-items: {_self.image_alignment};
align-items: {image_alignment};
}}
</style>
""",
Expand All @@ -156,34 +161,35 @@ def create_library(_self, number_of_columns, show_details):
try:
img_meta = get_image_size.get_image_metadata(img)
img_path = Path(img).resolve()
new_name = st.text_input(label="Name:", key=f"{img_path.stem}_{_self.uid}_name_{_self.filename_idx}", value=f"{img_path.stem}")
st.text_input(label="Type:", key=f"{img_path.stem}_{_self.uid}_type_{_self.filename_idx}", value=f"{img_path.suffix.strip('.').upper()}", disabled=True)
new_name = st.text_input(label="Name:", key=f"{img_path.stem}_{uid}_name_{filename_idx}", value=f"{img_path.stem}")
st.text_input(label="Type:", key=f"{img_path.stem}_{uid}_type_{filename_idx}", value=f"{img_path.suffix.strip('.').upper()}", disabled=True)
details_col1, details_col2 = st.columns(2)
del_check = st.checkbox(label="Delete ?", key=f"{img_path.stem}_{_self.uid}_del_check_{_self.filename_idx}", help="Permanently delete a file from the library.")
del_check = st.checkbox(label="Delete ?", key=f"{img_path.stem}_{uid}_del_check_{filename_idx}", help="Permanently delete a file from the library.")
if del_check:
st.button(label="Delete", key=f"{img_path.stem}_{_self.uid}_delete_button_{_self.filename_idx}", type="secondary", use_container_width=True, on_click=_self.update_file, args=(img_path, new_name, del_check))
st.button(label="Delete", key=f"{img_path.stem}_{uid}_delete_button_{filename_idx}", type="secondary", use_container_width=True, on_click=_self.update_file, args=(img_path, new_name, del_check))
else:
st.button(label="Update", key=f"{img_path.stem}_{_self.uid}_submit_button_{_self.filename_idx}", type="primary", use_container_width=True, on_click=_self.update_file, args=(img_path, new_name, del_check))
st.button(label="Update", key=f"{img_path.stem}_{uid}_submit_button_{filename_idx}", type="primary", use_container_width=True, on_click=_self.update_file, args=(img_path, new_name, del_check))
with details_col1:
st.text_input(label="Width:", key=f"{img_path.stem}_{_self.uid}_width_{_self.filename_idx}", value=f"{img_meta.width}", disabled=True)
st.text_input(label="Width:", key=f"{img_path.stem}_{uid}_width_{filename_idx}", value=f"{img_meta.width}", disabled=True)
with details_col2:
st.text_input(label="Height:", key=f"{img_path.stem}_{_self.uid}_height_{_self.filename_idx}", value=f"{img_meta.height}", disabled=True)
st.text_input(label="Height:", key=f"{img_path.stem}_{uid}_height_{filename_idx}", value=f"{img_meta.height}", disabled=True)
except get_image_size.UnknownImageFormat:
width, height = -1, -1
# Keeps track of the current column, if we reach the `max_idx` we reset it
# to 0 and increase the row index. This combined with the slicing should
# ensure all images, details and buttons are in the correct columns.
if _self.col_idx < _self.max_idx:
_self.col_idx += 1
if col_idx < max_idx:
col_idx += 1
else:
_self.col_idx = 0
_self.library_rows_idx += 1
_self.filename_idx += 1
return _self.library_container
col_idx = 0
library_rows_idx += 1
filename_idx += 1
return library_gallery_container
'''

library = Library(directory="assets")
library_columns = Library(directory="assets", number_of_columns=4, uid="columns")
library = Library(directory="assets/landscape/")
library_columns = Library(directory="assets/portrait/", number_of_columns=4, uid="library-columns")
library_mixed = Library(directory="assets/mixed/", uid="mixed-library")

with st.expander(label="**Source Code**", expanded=True):
st.code(body=source_code)
1 change: 0 additions & 1 deletion pages/Uploads.py
Expand Up @@ -4,7 +4,6 @@
# Configure page title, layout, menu items and links.
st.set_page_config(
page_title="Streamlit Uploads Library",
initial_sidebar_state="expanded",
layout="wide",
menu_items={
"Get Help": "https://github.com/hreikin/streamlit-uploads-library",
Expand Down

0 comments on commit 4aa8348

Please sign in to comment.