Malaji71 commited on
Commit
24e24ac
Β·
verified Β·
1 Parent(s): 1256f85

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -7
app.py CHANGED
@@ -115,10 +115,76 @@ st.markdown("""
115
  color: #E53E3E;
116
  font-weight: bold;
117
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  </style>
119
  """, unsafe_allow_html=True)
120
 
121
- # Function to safely get value or return default
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  def safe_get(row, key, default="N/A"):
123
  try:
124
  # Special handling for Name field
@@ -263,11 +329,14 @@ def create_sample_data():
263
  }
264
 
265
  # Header
266
- col1, col2 = st.columns([6, 1])
267
  with col1:
268
  st.markdown("# πŸ›‘οΈ Terror Finance & Maritime Watch")
 
269
  with col2:
270
  theme_toggle = st.checkbox("πŸŒ™", key="theme")
 
 
271
 
272
  # Load data
273
  try:
@@ -536,7 +605,7 @@ with tab3:
536
  )
537
 
538
  # Filters for vessels
539
- col1, col2, col3 = st.columns([3, 2, 2])
540
 
541
  with col1:
542
  name_filter = st.text_input("Search vessels", placeholder="Enter vessel name or IMO...", key="search_vessels")
@@ -555,6 +624,13 @@ with tab3:
555
  status_options += sorted([s for s in statuses if s and s.lower() != 'nan'])
556
  status_filter = st.selectbox("Status", status_options, key="status_vessels")
557
 
 
 
 
 
 
 
 
558
  # Apply filters
559
  filtered_vessels = data['vessels'].copy()
560
 
@@ -563,7 +639,8 @@ with tab3:
563
  mask = (
564
  filtered_vessels['Name'].str.contains(name_filter, case=False, na=False) |
565
  filtered_vessels.get('IMO', pd.Series()).astype(str).str.contains(name_filter, case=False, na=False) |
566
- filtered_vessels.get('Owner', pd.Series()).astype(str).str.contains(name_filter, case=False, na=False)
 
567
  )
568
  filtered_vessels = filtered_vessels[mask]
569
 
@@ -576,6 +653,11 @@ with tab3:
576
  filtered_vessels = filtered_vessels[
577
  filtered_vessels['Status'] == status_filter
578
  ]
 
 
 
 
 
579
 
580
  # Display vessels
581
  for _, vessel in filtered_vessels.iterrows():
@@ -699,6 +781,12 @@ with tab5:
699
 
700
  # Footer
701
  st.markdown("---")
702
- st.markdown("πŸ›‘οΈ **Terror Finance & Maritime Watch** - Monitoring entities involved in terror financing and maritime sanctions evasion")
703
- st.markdown(f"πŸ“Š Data processed: {len(data['individuals'])} individuals, {len(data['companies'])} companies, {len(data['vessels'])} vessels")
704
- st.markdown(f"πŸ•’ Last updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
 
 
 
 
 
 
 
115
  color: #E53E3E;
116
  font-weight: bold;
117
  }
118
+
119
+ /* Pariente AI Branding */
120
+ .pariente-ai {
121
+ color: #4A5568;
122
+ font-size: 0.875rem;
123
+ font-style: italic;
124
+ text-align: right;
125
+ }
126
+ .pariente-ai-footer {
127
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
128
+ -webkit-background-clip: text;
129
+ -webkit-text-fill-color: transparent;
130
+ font-weight: bold;
131
+ }
132
  </style>
133
  """, unsafe_allow_html=True)
134
 
135
+ # Function to extract IMO from Information field
136
+ def extract_imo_from_info(info_text):
137
+ """Extract IMO number from Information field"""
138
+ import re
139
+ if not info_text or pd.isna(info_text):
140
+ return "N/A"
141
+
142
+ # Look for IMO pattern: IMO- followed by 7 digits
143
+ imo_match = re.search(r'IMO-?\s*(\d{7})', str(info_text), re.IGNORECASE)
144
+ if imo_match:
145
+ return imo_match.group(1)
146
+ return "N/A"
147
+
148
+ def extract_mmsi_from_info(info_text):
149
+ """Extract MMSI from Information field"""
150
+ import re
151
+ if not info_text or pd.isna(info_text):
152
+ return "N/A"
153
+
154
+ # Look for MMSI pattern
155
+ mmsi_match = re.search(r'MMSI-?\s*(\d{9})', str(info_text), re.IGNORECASE)
156
+ if mmsi_match:
157
+ return mmsi_match.group(1)
158
+ return "N/A"
159
+
160
+ def extract_call_sign_from_info(info_text):
161
+ """Extract Call Sign from Information field"""
162
+ import re
163
+ if not info_text or pd.isna(info_text):
164
+ return "N/A"
165
+
166
+ # Look for Call Sign pattern
167
+ call_match = re.search(r'Call Sign-?\s*([A-Z0-9]+)', str(info_text), re.IGNORECASE)
168
+ if call_match:
169
+ return call_match.group(1)
170
+ return "N/A"
171
+
172
+ def extract_owner_from_info(info_text):
173
+ """Extract owner information from Information field"""
174
+ import re
175
+ if not info_text or pd.isna(info_text):
176
+ return "N/A"
177
+
178
+ # Look for Registered owner or Commercial manager
179
+ owner_match = re.search(r'Registered owner-?\s*([^,]+)', str(info_text), re.IGNORECASE)
180
+ if owner_match:
181
+ return owner_match.group(1).strip()
182
+
183
+ manager_match = re.search(r'Commercial manager-?\s*([^,]+)', str(info_text), re.IGNORECASE)
184
+ if manager_match:
185
+ return manager_match.group(1).strip()
186
+
187
+ return "N/A"
188
  def safe_get(row, key, default="N/A"):
189
  try:
190
  # Special handling for Name field
 
329
  }
330
 
331
  # Header
332
+ col1, col2, col3 = st.columns([6, 1, 1])
333
  with col1:
334
  st.markdown("# πŸ›‘οΈ Terror Finance & Maritime Watch")
335
+ st.markdown("*Powered by Pariente AI - Advanced Intelligence Analytics*")
336
  with col2:
337
  theme_toggle = st.checkbox("πŸŒ™", key="theme")
338
+ with col3:
339
+ st.markdown('<div class="pariente-ai">πŸ€– <span class="pariente-ai-footer">Pariente AI</span><br><em>Intelligence Platform</em></div>', unsafe_allow_html=True)
340
 
341
  # Load data
342
  try:
 
605
  )
606
 
607
  # Filters for vessels
608
+ col1, col2, col3, col4 = st.columns([3, 2, 2, 2])
609
 
610
  with col1:
611
  name_filter = st.text_input("Search vessels", placeholder="Enter vessel name or IMO...", key="search_vessels")
 
624
  status_options += sorted([s for s in statuses if s and s.lower() != 'nan'])
625
  status_filter = st.selectbox("Status", status_options, key="status_vessels")
626
 
627
+ with col4:
628
+ org_options = ["All Organizations"]
629
+ if len(data['vessels']) > 0 and 'Linked To' in data['vessels'].columns:
630
+ orgs = data['vessels']['Linked To'].dropna().astype(str).unique()
631
+ org_options += sorted([o for o in orgs if o and o.lower() != 'nan'])
632
+ org_filter = st.selectbox("Organization", org_options, key="org_vessels")
633
+
634
  # Apply filters
635
  filtered_vessels = data['vessels'].copy()
636
 
 
639
  mask = (
640
  filtered_vessels['Name'].str.contains(name_filter, case=False, na=False) |
641
  filtered_vessels.get('IMO', pd.Series()).astype(str).str.contains(name_filter, case=False, na=False) |
642
+ filtered_vessels.get('Owner', pd.Series()).astype(str).str.contains(name_filter, case=False, na=False) |
643
+ filtered_vessels.get('Information', pd.Series()).astype(str).str.contains(name_filter, case=False, na=False)
644
  )
645
  filtered_vessels = filtered_vessels[mask]
646
 
 
653
  filtered_vessels = filtered_vessels[
654
  filtered_vessels['Status'] == status_filter
655
  ]
656
+
657
+ if org_filter != "All Organizations":
658
+ filtered_vessels = filtered_vessels[
659
+ filtered_vessels['Linked To'] == org_filter
660
+ ]
661
 
662
  # Display vessels
663
  for _, vessel in filtered_vessels.iterrows():
 
781
 
782
  # Footer
783
  st.markdown("---")
784
+ col1, col2 = st.columns([3, 1])
785
+ with col1:
786
+ st.markdown("πŸ›‘οΈ **Terror Finance & Maritime Watch** - Monitoring entities involved in terror financing and maritime sanctions evasion")
787
+ st.markdown(f"πŸ“Š Data processed: {len(data['individuals'])} individuals, {len(data['companies'])} companies, {len(data['vessels'])} vessels")
788
+ st.markdown(f"πŸ•’ Last updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
789
+ with col2:
790
+ st.markdown("**Powered by**")
791
+ st.markdown("πŸ€– **Pariente AI**")
792
+ st.markdown("*Advanced Intelligence Analytics*")