Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import json | |
| import os | |
| import re | |
| CONTACT_FILE = "contacts.csv" | |
| LISTS_FILE = "saved_lists.json" | |
| MATRIX_FILE = "channel_matrix.xlsx" | |
| DOC_FILE = "CHANNELS LIST.docx" | |
| st.set_page_config(layout="wide", page_title="Skype Contact Manager") | |
| # Load contacts | |
| def load_contacts(): | |
| df = pd.read_csv(CONTACT_FILE, encoding="ISO-8859-1") | |
| if "checkbox" not in df.columns: | |
| df["checkbox"] = False | |
| return df | |
| # Extract +tags (case-insensitive, non-numeric) | |
| def extract_tags(df): | |
| tags = set() | |
| for name in df["display_name"]: | |
| tokens = re.findall(r'\+\w+', str(name)) | |
| tags.update([t.lower() for t in tokens if not re.match(r'\+\d+', t)]) | |
| return sorted(tags) | |
| # Load saved lists | |
| def load_saved_lists(): | |
| if os.path.exists(LISTS_FILE): | |
| with open(LISTS_FILE, "r") as f: | |
| return json.load(f) | |
| return {} | |
| # Save lists to file | |
| def save_lists(lists): | |
| with open(LISTS_FILE, "w") as f: | |
| json.dump(lists, f, indent=2) | |
| # UI β Filter tags | |
| def tag_filter_ui(df): | |
| st.header("π Filter Contacts by Tags") | |
| tags = extract_tags(df) | |
| filter_mode = st.radio("Filter Mode", ["AND", "OR"], horizontal=True) | |
| selected_tags = [] | |
| cols = st.columns(6) | |
| for i, tag in enumerate(tags): | |
| if cols[i % 6].checkbox(tag): | |
| selected_tags.append(tag) | |
| if selected_tags: | |
| def match_tags(name): | |
| found = [t.lower() for t in re.findall(r'\+\w+', str(name)) if not re.match(r'\+\d+', t)] | |
| if filter_mode == "AND": | |
| return all(tag in found for tag in selected_tags) | |
| else: | |
| return any(tag in found for tag in selected_tags) | |
| df = df[df["display_name"].apply(match_tags)] | |
| return df, selected_tags | |
| # UI β Select & Save lists | |
| def select_and_save_ui(df, saved_lists): | |
| st.header("β Select Contacts & Save as List") | |
| selection_df = df[["display_name"]].copy() | |
| selection_df["checkbox"] = False | |
| edited_df = st.data_editor(selection_df, num_rows="fixed", use_container_width=True) | |
| # Save list | |
| list_name = st.text_input("List Name") | |
| if st.button("πΎ Save Selected Contacts"): | |
| selected = edited_df[edited_df["checkbox"] == True]["display_name"].tolist() | |
| if list_name and selected: | |
| saved_lists[list_name] = selected | |
| save_lists(saved_lists) | |
| st.success(f"Saved list '{list_name}' with {len(selected)} contacts.") | |
| # Load existing list | |
| st.subheader("π Load or Edit Saved List") | |
| if saved_lists: | |
| selected_list = st.selectbox("Choose a Saved List", list(saved_lists.keys())) | |
| if selected_list: | |
| st.markdown(f"**π Contacts in '{selected_list}'**") | |
| selected = st.multiselect("Modify this list:", df["display_name"].tolist(), default=saved_lists[selected_list]) | |
| if st.button("πΎ Update List"): | |
| saved_lists[selected_list] = selected | |
| save_lists(saved_lists) | |
| st.success("List updated.") | |
| if st.button("ποΈ Delete List"): | |
| del saved_lists[selected_list] | |
| save_lists(saved_lists) | |
| st.warning(f"Deleted list: {selected_list}") | |
| # UI β Edit contacts | |
| def edit_contacts_ui(df): | |
| st.header("βοΈ Edit Contacts Inline") | |
| editable_df = st.data_editor(df[["display_name"]], use_container_width=True, key="edit_contacts") | |
| if st.button("πΎ Save Edited Contacts"): | |
| df["display_name"] = editable_df["display_name"] | |
| df.to_csv(CONTACT_FILE, index=False, encoding="ISO-8859-1") | |
| st.success("Contacts updated and saved.") | |
| # UI β Add contact | |
| def add_contact_ui(df): | |
| st.header("β Add New Contact") | |
| new_contact = st.text_input("Enter New Contact (with tags)") | |
| if st.button("β Add Contact"): | |
| if new_contact.strip(): | |
| new_row = pd.DataFrame({"display_name": [new_contact]}) | |
| for col in df.columns: | |
| if col not in new_row.columns: | |
| new_row[col] = False if col == "checkbox" else "" | |
| df = pd.concat([df, new_row[df.columns]], ignore_index=True) | |
| df.to_csv(CONTACT_FILE, index=False, encoding="ISO-8859-1") | |
| st.success("Contact added. Please refresh to see the change.") | |
| return df | |
| # UI β Channel Matrix | |
| def channel_matrix_ui(): | |
| st.header("π§ Channel Matrix Viewer") | |
| try: | |
| matrix_df = pd.read_excel(MATRIX_FILE) | |
| matrix_df = matrix_df.rename(columns={matrix_df.columns[0]: "Operator"}) | |
| charterers = list(matrix_df.columns[1:]) | |
| selected = st.selectbox("Select a Charterer", charterers) | |
| yes_ops = matrix_df[matrix_df[selected].astype(str).str.upper() == "YES"]["Operator"].dropna() | |
| no_ops = matrix_df[matrix_df[selected].astype(str).str.upper() == "NO"]["Operator"].dropna() | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.success("β Operators Who Work With Us") | |
| st.dataframe(yes_ops, use_container_width=True) | |
| with col2: | |
| st.error("β Operators Who Don't Work With Us") | |
| st.dataframe(no_ops, use_container_width=True) | |
| except Exception as e: | |
| st.warning(f"Matrix load failed: {e}") | |
| # UI β View Docx File | |
| def docx_viewer_ui(): | |
| st.header("π View CHANNELS LIST Document") | |
| try: | |
| import docx | |
| document = docx.Document(DOC_FILE) | |
| for para in document.paragraphs: | |
| st.markdown(para.text) | |
| except Exception as e: | |
| st.error(f"Could not load DOCX file: {e}") | |
| # ========================== MAIN ========================== | |
| df = load_contacts() | |
| saved_lists = load_saved_lists() | |
| tab1, tab2, tab3 = st.tabs(["π Contact Manager", "π Channel Matrix", "π New Channel List"]) | |
| with tab1: | |
| df, _ = tag_filter_ui(df) | |
| select_and_save_ui(df, saved_lists) | |
| edit_contacts_ui(df) | |
| df = add_contact_ui(df) | |
| with tab2: | |
| channel_matrix_ui() | |
| with tab3: | |
| docx_viewer_ui() | |