siddhartharyaai commited on
Commit
a0e9493
Β·
verified Β·
1 Parent(s): b6b5bb0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +134 -127
app.py CHANGED
@@ -1,133 +1,140 @@
1
- import streamlit as st
2
  import pandas as pd
3
- import json
4
- from datetime import datetime
5
  import os
 
6
 
7
- # Constants
8
- CONTACTS_FILE = "contacts.xlsx"
9
- SAVED_LISTS_FILE = "saved_lists.json"
10
- CHANNEL_MATRIX_FILE = "channel_matrix.xlsx"
11
- TAGS = [
12
- "+mini", "+hdy", "+smx", "+pmx", "+cape", "+med", "+atl", "+rsea",
13
- "+safr", "+pg", "+wci", "+eci", "+seas", "+feast", "+nopac", "+aus", "+aust"
14
- ]
15
-
16
- # Load contacts
17
- @st.cache_data
18
- def load_contacts():
19
- df = pd.read_excel(CONTACTS_FILE)
20
- df["checkbox"] = False
21
- return df
22
-
23
- # Save lists locally
24
- def save_new_list(name, contacts, tags):
25
- new_entry = {
26
- "list_name": name,
27
- "contacts": contacts,
28
- "tags": tags,
29
- "timestamp": datetime.now().isoformat()
30
- }
31
- if os.path.exists(SAVED_LISTS_FILE):
32
- with open(SAVED_LISTS_FILE, "r") as f:
33
- data = json.load(f)
34
- else:
35
- data = []
36
-
37
- # Overwrite if same name
38
- data = [d for d in data if d["list_name"] != name]
39
- data.append(new_entry)
40
-
41
- with open(SAVED_LISTS_FILE, "w") as f:
42
- json.dump(data, f, indent=2)
43
-
44
- # Load lists
45
- def load_saved_lists():
46
- if os.path.exists(SAVED_LISTS_FILE):
47
- with open(SAVED_LISTS_FILE, "r") as f:
48
- return json.load(f)
49
- return []
50
-
51
- # Delete list
52
- def delete_list(name):
53
- data = load_saved_lists()
54
- data = [d for d in data if d["list_name"] != name]
55
- with open(SAVED_LISTS_FILE, "w") as f:
56
- json.dump(data, f, indent=2)
57
-
58
- # UI: Contact Filter Tab
59
- def contact_filter_ui():
60
- st.markdown("## πŸ“‡ Skype Contacts: Saved Lists")
61
-
62
- df = load_contacts()
63
- country_col = "profile.locations[0].country"
64
- search = st.text_input("πŸ” Search by Display Name")
65
- if search:
66
- df = df[df["display_name"].str.contains(search, case=False, na=False)]
67
-
68
- # Logic choice
69
- logic = st.radio("Tag Match Type", ["OR", "AND"], horizontal=True)
70
- tag_selections = []
71
- st.markdown("### πŸ“Œ Filter by Tags")
72
- cols = st.columns(4)
73
  for i, tag in enumerate(TAGS):
74
- if cols[i % 4].checkbox(tag):
75
- tag_selections.append(tag)
76
 
77
- # Apply tag logic
78
- if tag_selections:
79
- if logic == "OR":
80
- tag_mask = df["display_name"].apply(lambda x: any(tag in str(x) for tag in tag_selections))
81
- else:
82
- tag_mask = df["display_name"].apply(lambda x: all(tag in str(x) for tag in tag_selections))
83
- df = df[tag_mask]
84
-
85
- # Show tick boxes
86
- st.markdown("### βœ… Tick Contacts to Save in a List")
87
- show_df = df[["display_name", country_col]].copy()
88
- show_df["checkbox"] = False
89
- edited_df = st.data_editor(show_df, num_rows="dynamic", use_container_width=True)
90
-
91
- # Save list
92
- ticked = edited_df[edited_df["checkbox"] == True]
93
- list_name = st.text_input("πŸ’Ύ Name this list")
94
- if st.button("Save List"):
95
- if list_name and not ticked.empty:
96
- save_new_list(list_name, ticked["display_name"].tolist(), ", ".join(tag_selections))
97
- st.success(f"List '{list_name}' saved.")
98
  else:
99
- st.warning("List name and at least one contact must be selected.")
100
-
101
- # Saved lists
102
- st.markdown("---\n### πŸ“ Manage Saved Lists")
103
- saved_lists = load_saved_lists()
104
- if not saved_lists:
105
- st.info("No saved lists yet.")
106
- for entry in saved_lists:
107
- with st.expander(f"πŸ“Œ {entry['list_name']} ({len(entry['contacts'])} contacts)"):
108
- st.write("Tags:", entry["tags"])
109
- st.write("Saved on:", entry["timestamp"])
110
- st.write("Contacts:", entry["contacts"])
111
- if st.button(f"πŸ—‘οΈ Delete '{entry['list_name']}'", key=entry["list_name"]):
112
- delete_list(entry["list_name"])
113
- st.rerun()
114
-
115
- # UI: Channel Matrix Tab
116
- def channel_matrix_ui():
117
- st.markdown("## πŸ“Š Channel Matrix Checker")
118
- df = pd.read_excel(CHANNEL_MATRIX_FILE)
119
- charterers = list(df.columns[1:])
120
- selected_charterer = st.selectbox("Select a Charterer", charterers)
121
- yes_df = df[df[selected_charterer].str.lower() == "yes"]
122
- no_df = df[df[selected_charterer].str.lower() == "no"]
123
- st.markdown(f"### βœ… Operators who work with us for **{selected_charterer}**'s cargoes:")
124
- st.dataframe(yes_df[["Operator"]], use_container_width=True)
125
- st.markdown(f"### ❌ Operators who won't work with us for **{selected_charterer}**'s cargoes:")
126
- st.dataframe(no_df[["Operator"]], use_container_width=True)
127
-
128
- # Tabs
129
- tab1, tab2 = st.tabs(["πŸ“‡ Contact Filter", "πŸ“Š Channel Matrix"])
130
- with tab1:
131
- contact_filter_ui()
132
- with tab2:
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 (CRH TRADING):")
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 (CRH TRADING):")
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}")