CoolFace
Apppublic

deployedApps/stringsimilar

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
app.py181 linesDownload Raw Back to root
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