siddhartharyaai commited on
Commit
2a8435c
Β·
verified Β·
1 Parent(s): 77b4dca

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +129 -122
app.py CHANGED
@@ -1,133 +1,140 @@
1
- import streamlit as st
2
  import pandas as pd
3
- import json
 
4
  import os
5
- from datetime import datetime
6
 
7
- CONTACT_FILE = "contacts.xlsx"
 
 
8
  MATRIX_FILE = "channel_matrix.xlsx"
9
- SAVED_LISTS_FILE = "saved_lists.json"
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
- st.set_page_config(page_title="Skype Contacts Manager", layout="wide")
 
12
 
13
- # Load contacts
14
- @st.cache_data
15
- def load_contacts():
16
- df = pd.read_excel(CONTACT_FILE)
17
- df["display_name"] = df["display_name"].astype(str).str.strip().str.lower()
18
  if "country" not in df.columns:
19
  df["country"] = "N/A"
20
- if "tags" not in df.columns:
21
- df["tags"] = ""
22
- return df
23
-
24
- df = load_contacts()
25
- if "checkbox" not in df.columns:
26
- df["checkbox"] = False
27
-
28
- # Load saved lists
29
- def load_saved_lists():
30
- if os.path.exists(SAVED_LISTS_FILE):
31
- with open(SAVED_LISTS_FILE, "r") as f:
32
- return json.load(f)
33
- return {}
34
-
35
- def save_list(name, contact_names, tags=[]):
36
- lists = load_saved_lists()
37
- lists[name] = {
38
- "contacts": contact_names,
39
- "tags": tags,
40
- "timestamp": datetime.now().isoformat()
41
- }
42
- with open(SAVED_LISTS_FILE, "w") as f:
43
- json.dump(lists, f)
44
-
45
- # UI: Filter & Editable Contact Table
46
- def contact_filter_ui():
47
- st.header("πŸ“ Skype Contact Manager")
48
-
49
- # Sidebar Tag Filter
50
- all_tags = sorted(set(tag for row in df["tags"] for tag in str(row).split()))
51
- selected_tags = st.sidebar.multiselect("πŸ“Œ Filter by Tags", options=all_tags)
52
- logic_mode = st.sidebar.radio("Tag Filter Logic", ["AND", "OR"])
53
-
54
- # Filter Contacts
55
  if selected_tags:
56
- if logic_mode == "AND":
57
- mask = df["tags"].apply(lambda x: all(tag in str(x).split() for tag in selected_tags))
 
 
58
  else:
59
- mask = df["tags"].apply(lambda x: any(tag in str(x).split() for tag in selected_tags))
60
- filtered_df = df[mask].copy()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  else:
62
- filtered_df = df.copy()
63
-
64
- # Editable Table
65
- with st.expander("βœ… Tick off contacts as you check them", expanded=False):
66
- edited_df = st.data_editor(
67
- filtered_df[["display_name", "country", "checkbox"]],
68
- num_rows="dynamic",
69
- key="editor"
70
- )
71
- for idx in edited_df.index:
72
- df.loc[df["display_name"] == edited_df.loc[idx, "display_name"], "checkbox"] = edited_df.loc[idx, "checkbox"]
73
-
74
- st.divider()
75
-
76
- # Save List Section
77
- def save_list_ui():
78
- st.subheader("πŸ’Ύ Save Selected List")
79
- ticked_contacts = df[df["checkbox"]]["display_name"].tolist()
80
-
81
- if not ticked_contacts:
82
- st.info("βœ… Tick contacts in the above section to create a list.")
83
- return
84
-
85
- list_name = st.text_input("List name")
86
- if st.button("Save List") and list_name:
87
- save_list(list_name, ticked_contacts)
88
- st.success(f"List '{list_name}' saved!")
89
-
90
- # Manage Saved Lists
91
- def load_list_ui():
92
- st.subheader("πŸ“‚ Load or Manage a Saved List")
93
- saved_lists = load_saved_lists()
94
- if not saved_lists:
95
- st.info("No saved lists yet.")
96
- return
97
-
98
- list_name = st.selectbox("Select a List", list(saved_lists.keys()))
99
- if list_name:
100
- contacts = saved_lists[list_name]["contacts"]
101
- st.write(f"List: **{list_name}** β€” {len(contacts)} contacts")
102
- st.write(", ".join(contacts))
103
-
104
- if st.button(f"❌ Delete '{list_name}'"):
105
- saved_lists.pop(list_name)
106
- with open(SAVED_LISTS_FILE, "w") as f:
107
- json.dump(saved_lists, f)
108
- st.success("List deleted!")
109
-
110
- # Channel Matrix
111
- def channel_matrix_ui():
112
- st.header("πŸ“Š Channel Matrix")
113
- matrix_df = pd.read_excel(MATRIX_FILE)
114
- matrix_df = matrix_df.rename(columns={matrix_df.columns[0]: "Operator"})
115
- charterers = list(matrix_df.columns[1:])
116
- selected = st.selectbox("Select a Charterer", charterers)
117
-
118
- yes_ops = matrix_df[matrix_df[selected].astype(str).str.upper() == "YES"]["Operator"]
119
- no_ops = matrix_df[matrix_df[selected].astype(str).str.upper() == "NO"]["Operator"]
120
-
121
- col1, col2 = st.columns(2)
122
- with col1:
123
- st.success("βœ… Operators who work with us")
124
- st.dataframe(pd.DataFrame({"Operator": yes_ops}), use_container_width=True)
125
- with col2:
126
- st.error("❌ Operators who won't work with us")
127
- st.dataframe(pd.DataFrame({"Operator": no_ops}), use_container_width=True)
128
-
129
- # Page Layout
130
- contact_filter_ui()
131
- save_list_ui()
132
- load_list_ui()
133
- channel_matrix_ui()
 
 
1
  import pandas as pd
2
+ import streamlit as st
3
+ import re
4
  import os
5
+ import json
6
 
7
+ st.set_page_config(page_title="Skype Tool + Charterer Matrix", layout="wide")
8
+
9
+ CONTACT_FILE = "contacts.csv"
10
  MATRIX_FILE = "channel_matrix.xlsx"
11
+ SAVE_FILE = "saved_lists.json"
12
+
13
+ tabs = st.tabs(["Contact Filter", "Channel Matrix"])
14
+
15
+ # Load or initialize saved lists
16
+ if os.path.exists(SAVE_FILE):
17
+ with open(SAVE_FILE, "r") as f:
18
+ saved_data = json.load(f)
19
+ else:
20
+ saved_data = {}
21
+
22
+ # TAB 1: Contact Filter Tool
23
+ with tabs[0]:
24
+ st.title("πŸ“’ Skype Contact Filter Tool")
25
 
26
+ TAGS = ["+mini", "+hdy", "+smx", "+pmx", "+cape", "+med", "+atl", "+rsea",
27
+ "+safr", "+pg", "+wci", "+eci", "+seas", "+feast", "+nopac", "+aus", "+aust"]
28
 
29
+ df = pd.read_csv(CONTACT_FILE)
30
+ df["display_name"] = df["display_name"].astype(str).str.lower()
 
 
 
31
  if "country" not in df.columns:
32
  df["country"] = "N/A"
33
+
34
+ filter_mode = st.radio("Filter Mode", ["AND", "OR"], horizontal=True)
35
+
36
+ st.markdown("### Select Tags to Filter")
37
+ selected_tags = []
38
+ cols = st.columns(6)
39
+ for i, tag in enumerate(TAGS):
40
+ if cols[i % 6].checkbox(tag):
41
+ selected_tags.append(tag)
42
+
43
+ ticked_contacts = []
44
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  if selected_tags:
46
+ filtered_df = df.copy()
47
+ if filter_mode == "AND":
48
+ for tag in selected_tags:
49
+ filtered_df = filtered_df[filtered_df["display_name"].str.contains(re.escape(tag))]
50
  else:
51
+ pattern = "|".join(re.escape(tag) for tag in selected_tags)
52
+ filtered_df = filtered_df[filtered_df["display_name"].str.contains(pattern)]
53
+
54
+ st.success(f"Found {len(filtered_df)} matching contacts.")
55
+
56
+ with st.expander("βœ… Tick off contacts as you check them", expanded=False):
57
+ for i, row in filtered_df.iterrows():
58
+ ticked = st.checkbox(f"**{row['display_name'].title()}** _( {row['country']} )_", key=f"contact_{i}")
59
+ if ticked:
60
+ ticked_contacts.append({"display_name": row["display_name"], "country": row["country"]})
61
+
62
+ # Save preset block
63
+ if ticked_contacts:
64
+ st.markdown("### πŸ’Ύ Save this list as a preset")
65
+ preset_name = st.text_input("Enter a name for this contact list")
66
+ if st.button("Save List"):
67
+ if preset_name:
68
+ saved_data[preset_name] = {
69
+ "tags": selected_tags,
70
+ "contacts": ticked_contacts
71
+ }
72
+ with open(SAVE_FILE, "w") as f:
73
+ json.dump(saved_data, f, indent=2)
74
+ st.success(f"List '{preset_name}' saved successfully!")
75
+ else:
76
+ st.warning("Please enter a name before saving.")
77
+
78
+ # Download button
79
+ csv_data = pd.DataFrame(ticked_contacts).to_csv(index=False)
80
+ st.download_button("πŸ“₯ Download Ticked Contacts as CSV", data=csv_data, file_name="ticked_contacts.csv", mime="text/csv")
81
  else:
82
+ st.info("Select at least one tag to filter the contacts.")
83
+
84
+ # Load and manage saved lists
85
+ st.markdown("---")
86
+ st.markdown("### πŸ“‚ Load or Manage a Saved List")
87
+ if saved_data:
88
+ selected_preset = st.selectbox("Select a saved contact list", list(saved_data.keys()))
89
+ if selected_preset:
90
+ st.markdown(f"**Tags:** `{', '.join(saved_data[selected_preset]['tags'])}`")
91
+ st.markdown("**Contacts in this list:**")
92
+ for c in saved_data[selected_preset]["contacts"]:
93
+ st.markdown(f"- **{c['display_name'].title()}** _( {c['country']} )_")
94
+
95
+ st.markdown("#### πŸ—‘οΈ Delete or Rename List")
96
+ col1, col2 = st.columns(2)
97
+ with col1:
98
+ if st.button("❌ Delete This List"):
99
+ del saved_data[selected_preset]
100
+ with open(SAVE_FILE, "w") as f:
101
+ json.dump(saved_data, f, indent=2)
102
+ st.success(f"Deleted list '{selected_preset}'. Please reload the page.")
103
+ with col2:
104
+ new_name = st.text_input("Rename List As", value=selected_preset)
105
+ if st.button("✏️ Rename"):
106
+ if new_name and new_name != selected_preset:
107
+ saved_data[new_name] = saved_data.pop(selected_preset)
108
+ with open(SAVE_FILE, "w") as f:
109
+ json.dump(saved_data, f, indent=2)
110
+ st.success(f"Renamed to '{new_name}'. Please reload the page.")
111
+ else:
112
+ st.info("No saved lists available yet.")
113
+
114
+ # TAB 2: Charterer-Operator Matrix
115
+ with tabs[1]:
116
+ st.title("πŸ“Š Channel Matrix Checker")
117
+
118
+ try:
119
+ matrix_df = pd.read_excel(MATRIX_FILE)
120
+ matrix_df = matrix_df.rename(columns={matrix_df.columns[0]: "Operator"})
121
+
122
+ charterers = list(matrix_df.columns[1:])
123
+ selected_charterer = st.selectbox("Select a Charterer", charterers)
124
+
125
+ if selected_charterer:
126
+ yes_ops = matrix_df[matrix_df[selected_charterer].astype(str).str.upper() == "YES"]["Operator"]
127
+ no_ops = matrix_df[matrix_df[selected_charterer].astype(str).str.upper() == "NO"]["Operator"]
128
+
129
+ col1, col2 = st.columns(2)
130
+ with col1:
131
+ st.success(f"βœ… Operators who work with us for {selected_charterer}'s cargoes:")
132
+ for name in yes_ops:
133
+ st.markdown(f"- **{name}**")
134
+ with col2:
135
+ st.error(f"❌ Operators who won't work with us for {selected_charterer}'s cargoes:")
136
+ for name in no_ops:
137
+ st.markdown(f"- {name}")
138
+ except Exception as e:
139
+ st.warning("Could not load matrix file. Please ensure 'channel_matrix.xlsx' exists.")
140
+ st.text(f"Error: {e}")