CoolFace
Apppublic

ajurasovic/MENA

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py169 linesDownload Raw Back to root
1import streamlit as st2import json3import ast4 5# Number of topics to display initially per section6INITIAL_VISIBLE_COUNT = 5  # Topics initially visible7TOPIC_INCREMENT = 5  # Number of additional topics shown per "Show More" click8KEYWORD_LIMIT = 10  # Maximum keywords shown initially9 10@st.cache_data11def load_topics_file():12    """Load topics data from topics.txt."""13    with open("topics.txt", "r", encoding="utf-8") as f:14        return f.read()15 16def safe_parse_keywords(keyword_str):17    """18    Safely parses a list of keywords from a given string.19    Handles various formatting issues like mismatched quotes.20    """21    keyword_str = keyword_str.strip()22 23    # Try parsing as a valid JSON array24    try:25        return json.loads(keyword_str)26    except json.JSONDecodeError:27        pass28 29    # Try parsing as a Python literal (handles improperly formatted JSON-like lists)30    try:31        parsed_keywords = ast.literal_eval(keyword_str)32        if isinstance(parsed_keywords, list):33            return parsed_keywords34    except (SyntaxError, ValueError):35        pass36 37    # If parsing fails, return an empty list and log an error38    st.error(f"Error parsing keywords: {keyword_str}")39    return []40 41def parse_topics_from_text(text):42    """43    Parses topics from the structured text section and organizes them into competitive and opportunity topics.44    """45    lines = text.split("\n")46    current_section = None47    competitive_topics = []48    opportunity_topics = []49    current_topic = None50 51    # Ignore the JSON section (everything before '=== Topic Analysis Summary ===')52    start_parsing = False53 54    for line in lines:55        line = line.strip()56        if not line:57            continue58 59        # Detect the start of the relevant section60        if "=== Topic Analysis Summary ===" in line:61            start_parsing = True62            continue63 64        if not start_parsing:65            continue  # Skip everything before this section66 67        # Detect section headers68        if "Competitive Topics" in line:69            if current_topic and current_section == "competitive":70                competitive_topics.append(current_topic)71                current_topic = None72            current_section = "competitive"73            continue74        elif "Opportunity Topics" in line:75            if current_topic:76                if current_section == "competitive":77                    competitive_topics.append(current_topic)78                elif current_section == "opportunity":79                    opportunity_topics.append(current_topic)80                current_topic = None81            current_section = "opportunity"82            continue83 84        # Parse topic details85        if line.startswith("Topic:"):86            if current_topic:87                if current_section == "competitive":88                    competitive_topics.append(current_topic)89                elif current_section == "opportunity":90                    opportunity_topics.append(current_topic)91            current_topic = {}92            current_topic["title"] = line.replace("Topic:", "").strip()93        elif line.startswith("Total Volume:"):94            current_topic["totalVolume"] = float(line.replace("Total Volume:", "").strip())95        elif line.startswith("Average KD:"):96            current_topic["avgKD"] = float(line.replace("Average KD:", "").strip())97        elif line.startswith("Keyword Count:"):98            current_topic["keywordCount"] = int(line.replace("Keyword Count:", "").strip())99        elif line.startswith("Keywords:"):100            keyword_str = line.replace("Keywords:", "").strip()101            current_topic["keywords"] = safe_parse_keywords(keyword_str)102 103    # Append the last topic if exists104    if current_topic:105        if current_section == "competitive":106            competitive_topics.append(current_topic)107        elif current_section == "opportunity":108            opportunity_topics.append(current_topic)109 110    return competitive_topics, opportunity_topics111 112def display_topics(section_title, topics, key_prefix):113    """Displays topics in a paginated manner with keyword expansion options."""114    st.subheader(section_title)115 116    # Track how many topics to show117    if f"{key_prefix}_visible_count" not in st.session_state:118        st.session_state[f"{key_prefix}_visible_count"] = INITIAL_VISIBLE_COUNT119 120    visible_count = st.session_state[f"{key_prefix}_visible_count"]121 122    for idx, topic in enumerate(topics[:visible_count]):123        st.markdown(f"**{topic['title']}**")124        st.write(f"Total Volume: {topic['totalVolume']}")125        st.write(f"Avg KD: {topic['avgKD']}")126 127        # Keywords: Show up to 10 initially, with a "Show All" button128        keyword_key = f"{key_prefix}_keywords_{idx}"129        if keyword_key not in st.session_state:130            st.session_state[keyword_key] = False  # Default to collapsed keywords131 132        if len(topic["keywords"]) > KEYWORD_LIMIT:133            if not st.session_state[keyword_key]:  # Show only first 10 keywords134                st.write(f"Keywords: {', '.join(topic['keywords'][:KEYWORD_LIMIT])} ...")135                if st.button("Show All", key=f"show_{keyword_key}"):136                    st.session_state[keyword_key] = True137                    st.rerun()138            else:  # Show full list of keywords139                st.write(f"Keywords: {', '.join(topic['keywords'])}")140        else:141            st.write(f"Keywords: {', '.join(topic['keywords'])}")142 143        st.markdown("---")144 145    # "Show More" Button for paginated topic loading146    if visible_count < len(topics):147        if st.button("Show More", key=f"show_more_{key_prefix}"):148            st.session_state[f"{key_prefix}_visible_count"] += TOPIC_INCREMENT149            st.rerun()150 151def main():152    st.title("JNS Topics")153 154    # Load and parse the topics file155    text = load_topics_file()156    competitive_topics, opportunity_topics = parse_topics_from_text(text)157 158    # Create two columns for competitive and opportunity topics159    col1, col2 = st.columns(2)160 161    with col1:162        display_topics("Competitive Topics", competitive_topics, "competitive")163 164    with col2:165        display_topics("Opportunity Topics", opportunity_topics, "opportunity")166 167if __name__ == "__main__":168    main()169