joschetan commited on
Commit
cd4fbc8
·
verified ·
1 Parent(s): c8d9213

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -322
app.py CHANGED
@@ -1,335 +1,45 @@
1
- import streamlit as st
2
  import pandas as pd
3
  import requests
4
  import json
5
- import base64
6
- from io import BytesIO
7
  import openpyxl
8
- import os
9
-
10
- # 📌 0. Hugging Face ScriptRunContext Patch (To avoid runtime warnings)
11
- from streamlit.runtime.scriptrunner_utils.script_run_context import add_script_run_ctx
12
- import threading
13
-
14
- # 📌 1. Mukhya Page Configuration
15
- st.set_page_config(
16
- page_title="CK Export Invoice Processor Pro",
17
- page_icon="🚢",
18
- layout="wide",
19
- initial_sidebar_state="expanded"
20
- )
21
 
22
  WEB_APP_URL = "https://script.google.com/macros/s/AKfycbwEsmWdnkVW3H7_fD99vPMrqhvmY6iJHP1ZooKuwDlj2VE4cht_FBgFyem9xDRFlbjuNw/exec"
23
  SPREADSHEET_ID = "182qRuH7R0jZqWVKHCg_oAG1SK5CUSkQpxVPxH2O8QUQ"
24
 
25
- def fetch_all_from_sheet():
26
- """गूगल शीट से JSON डेटा, टेम्पलेट्स, API Key और Exchange Rates एक साथ फेच करता है (Session State Caching के साथ)"""
27
- if "gsheet_master_cache" in st.session_state and st.session_state["gsheet_master_cache"] is not None:
28
- return st.session_state["gsheet_master_cache"]
29
-
30
- try:
31
- response = requests.get(f"{WEB_APP_URL}?action=get_data", timeout=20)
32
- if response.status_code == 200:
33
- res_text = response.text.strip()
34
- if res_text.startswith("<"):
35
- return None
36
- data = response.json()
37
- st.session_state["gsheet_master_cache"] = data
38
- return data
39
- except Exception:
40
- pass
41
- return None
42
-
43
- def clear_sheet_cache():
44
- if "gsheet_master_cache" in st.session_state:
45
- st.session_state["gsheet_master_cache"] = None
46
-
47
- def save_exchange_rates_to_sheet(ex_data):
48
- try:
49
- payload = {
50
- "action": "save_exchange_rates",
51
- "exchange_data": ex_data
52
- }
53
- res = requests.post(WEB_APP_URL, data=json.dumps(payload), timeout=30)
54
- if res.status_code == 200:
55
- clear_sheet_cache()
56
- return True
57
- return False
58
- except Exception:
59
- return False
60
-
61
- # 📌 2. Session State Initialization (Global App Lock ke liye)
62
- if "app_authenticated" not in st.session_state:
63
- st.session_state["app_authenticated"] = False
64
-
65
- # 🔒 Agar app unlock nahi hai, toh pehle password screen dikhayein
66
- if not st.session_state["app_authenticated"]:
67
- col1, col2, col3 = st.columns([1, 1.5, 1])
68
- with col2:
69
- st.markdown("<br><br>", unsafe_allow_html=True)
70
- st.markdown("<h2 style='text-align: center;'>🚢 CK Export Invoice Processor Pro</h2>", unsafe_allow_html=True)
71
- st.markdown("<p style='text-align: center; color: gray;'>Kripya aage badhne ke liye app ka password darj karein.</p>", unsafe_allow_html=True)
72
-
73
- with st.form(key="login_form"):
74
- pass_input = st.text_input("Password darj karein:", type="password", key="global_lock_pwd")
75
- submit_button = st.form_submit_button("Unlock App", use_container_width=True, type="primary")
76
-
77
- if submit_button:
78
- if pass_input == "CKJ":
79
- st.session_state["app_authenticated"] = True
80
- st.rerun()
81
- else:
82
- st.error("❌ Galat password! Kripya sahi password darj karein.")
83
- st.stop()
84
-
85
- # ==========================================
86
- # 🚀 Password sahi hone ke baad dikhne wala main app code
87
- # ==========================================
88
-
89
- st.markdown("""
90
- <style>
91
- [data-testid="stSidebarCollapseButton"] { display: none !important; }
92
- [data-testid="stSidebarCollapsedControl"] { display: none !important; }
93
- .creator-card {
94
- background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
95
- padding: 15px;
96
- border-radius: 12px;
97
- color: white;
98
- text-align: center;
99
- box-shadow: 0 4px 10px rgba(0,0,0,0.2);
100
- margin-bottom: 12px;
101
- margin-top: 10px;
102
- }
103
- .creator-name {
104
- font-size: 18px;
105
- font-weight: 700;
106
- margin-top: 8px;
107
- margin-bottom: 2px;
108
- }
109
- .creator-title {
110
- font-size: 12px;
111
- color: #d1d8e0;
112
- letter-spacing: 1px;
113
- text-transform: uppercase;
114
- font-weight: 600;
115
- }
116
- [data-testid="stMetricValue"] {
117
- font-size: 18px !important;
118
- }
119
- [data-testid="stMetricLabel"] {
120
- font-size: 12px !important;
121
- }
122
- </style>
123
- """, unsafe_allow_html=True)
124
-
125
- with st.sidebar:
126
- st.markdown("<br>", unsafe_allow_html=True)
127
-
128
- # 1. Sabse upar: Photo
129
  try:
130
- st.image("ck_photo.jpg", use_container_width=True)
131
- except:
132
- st.info("Photo loading...")
133
-
134
- # 2. Uske niche: Chetan Joshi wala blue profile card
135
- st.markdown("""
136
- <div class="creator-card">
137
- <div class="creator-name">Chetan Joshi</div>
138
- <div class="creator-title">📞 +91 98253 06898</div>
139
- <hr style="border-color: rgba(255,255,255,0.2); margin: 8px 0;">
140
- <p style='font-size: 11px; color: #f1f2f6; margin: 0;'>
141
- <b>CK Export Invoice Pro v2.0</b><br>
142
- Enterprise Automation & Precision.
143
- </p>
144
- </div>
145
- """, unsafe_allow_html=True)
146
-
147
- # Session State & Google Sheet Fetch for Exchange Rates
148
- if "exchange_rates" not in st.session_state or not isinstance(st.session_state["exchange_rates"], dict):
149
- sheet_full_data = fetch_all_from_sheet()
150
- sheet_ex = sheet_full_data.get("exchange_rates", None) if isinstance(sheet_full_data, dict) else None
151
-
152
- if sheet_ex and isinstance(sheet_ex, dict):
153
- st.session_state["exchange_rates"] = sheet_ex
154
- else:
155
- st.session_state["exchange_rates"] = {
156
- "date": "21-08-2026",
157
- "rates": {"EUR": "109.8", "GBP": "128.15", "USD": "94.8"},
158
- "all_rates": {}
159
- }
160
-
161
- ex_data = st.session_state["exchange_rates"]
162
- if "date" not in ex_data: ex_data["date"] = "21-08-2026"
163
- if "rates" not in ex_data: ex_data["rates"] = {"EUR": "109.8", "GBP": "128.15", "USD": "94.8"}
164
- if "all_rates" not in ex_data: ex_data["all_rates"] = {}
165
-
166
- # 3. Uske niche: Teen currencies (EUR, GBP, USD) chote font mein
167
- r = ex_data["rates"]
168
- col_e, col_g, col_u = st.columns(3)
169
- with col_e: st.metric(label="EUR", value=r.get("EUR", "109.8"))
170
- with col_g: st.metric(label="GBP", value=r.get("GBP", "128.15"))
171
- with col_u: st.metric(label="USD", value=r.get("USD", "94.8"))
172
-
173
- # 4. Uske niche: Bohat Badi Size mein Effective Date (w.e.f)
174
- st.markdown(f"<div style='text-align: center; margin-top: 10px; margin-bottom: 12px;'><span style='font-size: 20px; font-weight: 800; color: #00cec9; background: rgba(0, 206, 201, 0.1); padding: 4px 10px; border-radius: 6px; display: inline-block;'>📅 w.e.f: {ex_data.get('date', 'N/A')}</span></div>", unsafe_allow_html=True)
175
-
176
- # 5. Uske niche: Customs Exchange Rates heading aur PDF uploader
177
- st.markdown("##### 💱 Customs Exchange Rates")
178
-
179
- if "processed_ex_file_id" not in st.session_state:
180
- st.session_state["processed_ex_file_id"] = None
181
-
182
- ex_pdf = st.file_uploader("➡️ Upload Rate PDF", type=["pdf"], key="ex_pdf_sidebar")
183
- if ex_pdf is not None:
184
- file_signature = f"{ex_pdf.name}_{ex_pdf.size}"
185
- if st.session_state["processed_ex_file_id"] != file_signature:
186
- import pdfplumber
187
- import re
188
- try:
189
- with pdfplumber.open(ex_pdf) as pdf:
190
- text = ""
191
- for page in pdf.pages:
192
- t = page.extract_text()
193
- if t: text += t + "\n"
194
-
195
- date_match = re.search(r"w\.e\.f[\s\.:]*([\d]{2}[\-\/][\d]{2}[\-\/][\d]{4})", text, re.IGNORECASE)
196
- if not date_match:
197
- date_match = re.search(r"w\.e\.f[\s\.:]*([0-9A-Za-z\-]+)", text, re.IGNORECASE)
198
-
199
- if date_match:
200
- ex_data["date"] = date_match.group(1).strip()
201
-
202
- lines = text.split("\n")
203
- all_parsed = {}
204
- for line in lines:
205
- parts = line.split()
206
- if len(parts) >= 5 and parts[0].isupper() and len(parts[0]) == 3:
207
- curr_code = parts[0]
208
- export_val = parts[-1]
209
- try:
210
- float(export_val)
211
- all_parsed[curr_code] = export_val
212
- except:
213
- pass
214
-
215
- if all_parsed:
216
- ex_data["all_rates"] = all_parsed
217
- for c in ["EUR", "GBP", "USD"]:
218
- if c in all_parsed:
219
- ex_data["rates"][c] = all_parsed[c]
220
-
221
- save_exchange_rates_to_sheet(ex_data)
222
- st.session_state["processed_ex_file_id"] = file_signature
223
-
224
- st.success(f"🎉 Rates updated & saved to Sheet (w.e.f {ex_data['date']})!")
225
- st.rerun()
226
- else:
227
- st.warning("⚠️ PDF se data nahi padha ja saka!")
228
- except Exception as e:
229
- st.error(f"Error: {str(e)}")
230
-
231
- # Expander to view all other currency rates
232
- if ex_data["all_rates"]:
233
- with st.expander("📉 View All Currencies"):
234
- for c_code, c_val in ex_data["all_rates"].items():
235
- st.markdown(f"**{c_code}**: `{c_val}`")
236
-
237
- st.markdown("---")
238
-
239
- if st.button("🔒 Lock App", use_container_width=True):
240
- st.session_state["app_authenticated"] = False
241
- st.rerun()
242
-
243
- st.markdown("---")
244
-
245
- @st.cache_data(show_spinner=False)
246
- def load_data_from_gsheet():
247
- """Sidhe 'Shipper_JSON_Database' sheet se sara data load karta hai"""
248
- shipper_db = {}
249
- master_rules_template = {}
250
-
251
- try:
252
- json_db_url = f"https://docs.google.com/spreadsheets/d/{SPREADSHEET_ID}/gviz/tq?tqx=out:csv&sheet=Shipper_JSON_Database"
253
- df_json = pd.read_csv(json_db_url)
254
- if not df_json.empty:
255
- df_json.columns = df_json.columns.str.strip()
256
- for _, row in df_json.iterrows():
257
- if "ShipperName" in df_json.columns and pd.notna(row["ShipperName"]):
258
- s_name = str(row["ShipperName"]).strip()
259
- if s_name and s_name.lower() != "nan":
260
- shipper_json_str = row["ShipperJSON"] if "ShipperJSON" in df_json.columns and pd.notna(row["ShipperJSON"]) else "{}"
261
- try:
262
- shipper_db[s_name] = json.loads(shipper_json_str)
263
- except:
264
- shipper_db[s_name] = {
265
- "allowed_uploads": ["Full Job Excel Format File"],
266
- "uploaded_files": {},
267
- "mapping_rules": {},
268
- "item_table_rules": {},
269
- "item_table_rule_name": "parser_welspun",
270
- "igst_config": {"lut_keywords": "", "paid_keywords": ""}
271
- }
272
  except Exception as e:
273
- st.error(f"Error loading Shipper_JSON_Database: {e}")
274
-
275
- return shipper_db, master_rules_template
276
-
277
- # 🔄 Data load engine
278
- if "shipper_database" not in st.session_state or "master_rules_template" not in st.session_state:
279
- db, m_template = load_data_from_gsheet()
280
- st.session_state["shipper_database"] = db
281
- st.session_state["master_rules_template"] = m_template
282
- st.session_state["master_types"] = ["Full Job Excel Format File"]
283
-
284
- if "admin_authenticated" not in st.session_state: st.session_state["admin_authenticated"] = False
285
- if "processed_file_ready" not in st.session_state: st.session_state["processed_file_ready"] = None
286
 
287
- # ==========================================
288
- # 🖥️ MAIN PAGE ROUTING DISPLAY
289
- # ==========================================
290
- if st.session_state["admin_authenticated"]:
291
- top_col1, top_col2 = st.columns([8, 2])
292
- with top_col1:
293
- st.title("🚢 CK Export Processor - Admin Mode")
294
- with top_col2:
295
- if st.button("🚪 Log Out Admin", type="primary", use_container_width=True):
296
- st.session_state["admin_authenticated"] = False
297
- st.rerun()
298
-
299
- st.write("---")
300
-
301
- sub_menu = st.radio(
302
- "📋 Admin settings chunein:",
303
- ["i. 🏢 Add Shipper Name & Setup", "iii. 🌍 Global Masters & Common Dictionaries"],
304
- horizontal=True
305
- )
306
- st.write("---")
307
-
308
- from shipper_data import render_shipper_data
309
- from global_masters import render_global_masters
310
 
311
- if sub_menu == "i. 🏢 Add Shipper Name & Setup":
312
- render_shipper_data()
313
- elif sub_menu == "iii. 🌍 Global Masters & Common Dictionaries":
314
- render_global_masters()
315
-
316
- else:
317
- from processor import render_processor
318
-
319
- col_l, col_c, col_r = st.columns([1, 5, 1])
320
- with col_c:
321
- st.title("🚢 CK Export Invoice Processor")
322
- st.write("---")
323
- render_processor()
324
 
325
- st.write("---")
326
- st.write("---")
327
-
328
- with st.expander("🛠️ Admin Settings Access"):
329
- pwd = st.text_input("Admin password darj karein:", type="password", key="main_admin_pwd")
330
- if st.button("Login Karein"):
331
- if pwd == "TEST":
332
- st.session_state["admin_authenticated"] = True
333
- st.rerun()
334
- else:
335
- st.error("Galat password!")
 
1
+ import gradio as gr
2
  import pandas as pd
3
  import requests
4
  import json
 
 
5
  import openpyxl
6
+ import pdfplumber
7
+ import re
8
+ import spaces
 
 
 
 
 
 
 
 
 
 
9
 
10
  WEB_APP_URL = "https://script.google.com/macros/s/AKfycbwEsmWdnkVW3H7_fD99vPMrqhvmY6iJHP1ZooKuwDlj2VE4cht_FBgFyem9xDRFlbjuNw/exec"
11
  SPREADSHEET_ID = "182qRuH7R0jZqWVKHCg_oAG1SK5CUSkQpxVPxH2O8QUQ"
12
 
13
+ @spaces.GPU
14
+ def process_rate_pdf(file_obj):
15
+ if file_obj is None:
16
+ return "Kripya PDF file upload karein!"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  try:
18
+ with pdfplumber.open(file_obj.name) as pdf:
19
+ text = ""
20
+ for page in pdf.pages:
21
+ t = page.extract_text()
22
+ if t: text += t + "\n"
23
+
24
+ date_match = re.search(r"w\.e\.f[\s\.:]*([\d]{2}[\-\/][\d]{2}[\-\/][\d]{4})", text, re.IGNORECASE)
25
+ rate_date = date_match.group(1).strip() if date_match else "N/A"
26
+ return f"🎉 PDF Parsed Successfully! w.e.f: {rate_date}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  except Exception as e:
28
+ return f"Error: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
31
+ gr.Markdown("# 🚢 CK Export Invoice Processor Pro")
32
+ gr.Markdown("ZeroGPU Enabled & Free Integration")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ with gr.Tab("Invoice Processor"):
35
+ gr.Markdown("### Upload your files here to process export invoices.")
36
+ file_input = gr.File(label="Upload Job Excel / PDF")
37
+ output_box = gr.Textbox(label="Processing Status")
 
 
 
 
 
 
 
 
 
38
 
39
+ with gr.Tab("Customs Exchange Rates"):
40
+ pdf_rate_input = gr.File(label="Upload Rate PDF", file_types=[".pdf"])
41
+ rate_output = gr.Textbox(label="Rate Status")
42
+ pdf_rate_input.change(fn=process_rate_pdf, inputs=pdf_rate_input, outputs=rate_output)
43
+
44
+ if __name__ == "__main__":
45
+ demo.launch()