deployedApps/stringsimilar
0
1import os2import streamlit as st3import pandas as pd4import io5import requests6from PIL import Image7import re8from concurrent.futures import ThreadPoolExecutor9import time10 11# -----------------------------12# ๐ฆ Load and Group Image Metadata13# -----------------------------14@st.cache_data15def load_data():16 df = pd.read_csv("metadata.csv")17 grouped = df.groupby("File Name").agg({18 "Player Name": lambda x: set(x),19 "embedding_text": lambda x: " ".join(str(i) for i in x),20 "URL": "first"21 }).reset_index()22 return grouped23 24# -----------------------------25# ๐ Match Rows with Max Word Overlap (Grouped)26# -----------------------------27def search_best_word_overlap(query, df):28 query_words = set(re.findall(r'\w+', query.lower()))29 30 def word_overlap_score(text):31 text_words = set(re.findall(r'\w+', str(text).lower()))32 return len(query_words.intersection(text_words))33 34 df["match_score"] = df["embedding_text"].apply(word_overlap_score)35 max_score = df["match_score"].max()36 37 if max_score == 0:38 return pd.DataFrame()39 40 matches = df[df["match_score"] == max_score].copy()41 return matches42 43# -----------------------------44# ๐ Helper: Get Drive Direct Link45# -----------------------------46def get_drive_view_url_and_direct_link(url):47 try:48 file_id = url.split("/d/")[1].split("/")[0]49 view_link = f"https://drive.google.com/file/d/{file_id}/view"50 direct_link = f"https://drive.google.com/uc?id={file_id}"51 return view_link, direct_link52 except Exception:53 return url, url54 55# -----------------------------56# ๐ Fetch Image Content Only57# -----------------------------58def fetch_image_content(direct_link, retries=3):59 for _ in range(retries):60 try:61 response = requests.get(direct_link)62 if response.status_code == 200 and 'image' in response.headers.get('Content-Type', ''):63 return response.content64 except Exception as e:65 print(f"โ Error fetching image: {e}")66 return None67 68# -----------------------------69# ๐ฅ Fetch Images Concurrently (Without Downloading)70# -----------------------------71def fetch_images_concurrently(image_urls):72 image_contents = []73 74 with ThreadPoolExecutor() as executor:75 image_contents = list(executor.map(fetch_image_content, image_urls))76 77 return image_contents78 79# -----------------------------80# ๐ผ๏ธ Display Results in Grid with Pagination81# -----------------------------82def display_images_paginated(images, images_per_page=6):83 total_images = len(images)84 total_pages = (total_images + images_per_page - 1) // images_per_page85 86 if "current_page" not in st.session_state:87 st.session_state.current_page = 088 89 start_idx = st.session_state.current_page * images_per_page90 end_idx = start_idx + images_per_page91 page_images = images[start_idx:end_idx]92 93 images_per_row = 394 rows = [page_images[i:i + images_per_row] for i in range(0, len(page_images), images_per_row)]95 96 with st.spinner("Loading images..."):97 for row_images in rows:98 cols = st.columns(images_per_row)99 for idx, img_data in enumerate(row_images):100 with cols[idx]:101 try:102 if img_data["image_content"]:103 image = Image.open(io.BytesIO(img_data["image_content"]))104 st.image(image, use_container_width=True)105 st.markdown(f"`{img_data['file_name']}`")106 st.markdown(f"[๐ Open in Drive]({img_data['view_link']})", unsafe_allow_html=True)107 else:108 raise ValueError("Empty image content")109 except Exception as e:110 st.warning(f"โ ๏ธ Failed to display image `{img_data['file_name']}`: {e}")111 112 st.divider()113 col1, col2, col3 = st.columns([1, 2, 1])114 115 with col1:116 if st.button("โฌ
๏ธ Previous") and st.session_state.current_page > 0:117 st.session_state.current_page -= 1118 119 with col3:120 if st.session_state.current_page < total_pages - 1:121 if st.button("Next โก๏ธ"):122 st.session_state.current_page += 1123 124 with col2:125 current_page_label = f"**Page {st.session_state.current_page + 1} of {total_pages}**"126 if total_pages > 1:127 st.markdown(current_page_label, unsafe_allow_html=True)128 129# -----------------------------130# ๐ Streamlit UI131# -----------------------------132st.set_page_config(page_title="๐ Cricket Image Finder", layout="wide")133st.title("๐ธ Cricket Image Search (String Similarity)")134 135query = st.text_input("Enter your query:", placeholder="e.g. Moeen Ali and Stephen Fleming")136 137if st.button("Search") and query:138 df = load_data()139 140 with st.spinner("Finding best matching images..."):141 matches_df = search_best_word_overlap(query, df)142 143 if matches_df.empty:144 st.warning("No matching rows found.")145 else:146 images = []147 direct_links = []148 149 for _, row in matches_df.iterrows():150 url = row.get("URL", "")151 view_link, direct_link = get_drive_view_url_and_direct_link(url)152 153 if not url or "drive.google.com" not in url:154 continue155 156 direct_links.append(direct_link)157 158 images.append({159 "file_name": row.get("File Name", "Unknown"),160 "player_names": ", ".join(row.get("Player Name", [])),161 "view_link": view_link,162 "image_content": None163 })164 165 with st.spinner("Finding images..."):166 image_contents = fetch_images_concurrently(direct_links)167 168 for i in range(min(len(images), len(image_contents))):169 images[i]["image_content"] = image_contents[i]170 171 if not images:172 st.warning("No valid images could be fetched.")173 else:174 st.session_state.matches = images175 st.session_state.current_page = 0176 st.success(f"Found {len(images)} matching images! โ
")177 178# Display results179if "matches" in st.session_state:180 display_images_paginated(st.session_state.matches)181 