Da-123 commited on
Commit
e7ad868
·
verified ·
1 Parent(s): 7c68554
.gitignore ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ .env
2
+ myenv/
3
+
4
+ __pycache__/
5
+ *.py[cod]
6
+ *.pyo
7
+ *.pyd
README.md CHANGED
@@ -10,4 +10,8 @@ pinned: false
10
  short_description: Answer any questions you have about the content of your mail
11
  ---
12
 
13
- An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).
 
 
 
 
 
10
  short_description: Answer any questions you have about the content of your mail
11
  ---
12
 
13
+ An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).
14
+
15
+
16
+
17
+ uvicorn main:app --reload
client/main.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+
3
+ import requests
4
+ import sys
5
+ from typing import Dict, Any
6
+
7
+ API_BASE = "http://127.0.0.1:8000/api/v1"
8
+
9
+ class EmailQueryCLI:
10
+ def __init__(self):
11
+ self.session = requests.Session()
12
+
13
+ def check_connection(self) -> bool:
14
+ """Check if API server is running"""
15
+ try:
16
+ response = self.session.get(f"{API_BASE}/health")
17
+ response.raise_for_status()
18
+ return True
19
+ except:
20
+ return False
21
+
22
+ def pretty_print_email(self, email: Dict) -> str:
23
+ """Format email for display"""
24
+ return f"""
25
+ 📧 {email['subject']}
26
+ 📅 {email['date']} {email['time']}
27
+ 💬 {email['content'][:200]}...
28
+ 🆔 {email['message_id'][:20]}...
29
+ {"─" * 60}"""
30
+
31
+ def handle_query(self, query: str):
32
+ """Handle a natural language query"""
33
+ print(f"\n🔍 Processing: '{query}'")
34
+
35
+ try:
36
+ # Try to get emails directly
37
+ response = self.session.post(
38
+ f"{API_BASE}/get_emails",
39
+ json={"query": query}
40
+ )
41
+
42
+ if response.status_code == 200:
43
+ data = response.json()
44
+ self.display_email_results(data)
45
+ return True
46
+
47
+ elif response.status_code == 400:
48
+ error_detail = response.json()["detail"]
49
+
50
+ # Check if we need email mapping
51
+ if isinstance(error_detail, dict) and error_detail.get("type") == "need_email_input":
52
+ mapping_success = self.handle_missing_mapping(error_detail)
53
+ if mapping_success and hasattr(self, '_retry_query'):
54
+ # Retry the query after successful mapping
55
+ print(f"🔄 Retrying query...")
56
+ delattr(self, '_retry_query')
57
+ return self.handle_query(query) # Recursive retry
58
+ return mapping_success
59
+ else:
60
+ print(f"❌ Error: {error_detail}")
61
+ return False
62
+ else:
63
+ print(f"❌ API Error: {response.status_code}")
64
+ return False
65
+
66
+ except Exception as e:
67
+ print(f"❌ Connection Error: {e}")
68
+ return False
69
+
70
+ def handle_missing_mapping(self, error_detail: Dict) -> bool:
71
+ """Handle case where email mapping is needed"""
72
+ sender_intent = error_detail["sender_intent"]
73
+ print(f"\n❓ {error_detail['message']}")
74
+
75
+ try:
76
+ email = input(f"📧 Enter email for '{sender_intent}': ").strip()
77
+ if not email or "@" not in email:
78
+ print("❌ Invalid email address")
79
+ return False
80
+
81
+ # Add the mapping
82
+ mapping_response = self.session.post(
83
+ f"{API_BASE}/add_email_mapping",
84
+ json={"name": sender_intent, "email": email}
85
+ )
86
+
87
+ if mapping_response.status_code == 200:
88
+ print(f"✅ Mapping saved: '{sender_intent}' → '{email}'")
89
+ self._retry_query = True # Flag to retry the original query
90
+ return True
91
+ else:
92
+ print(f"❌ Failed to save mapping: {mapping_response.text}")
93
+ return False
94
+
95
+ except KeyboardInterrupt:
96
+ print("\n❌ Cancelled")
97
+ return False
98
+
99
+ def display_email_results(self, data: Dict):
100
+ """Display email search results"""
101
+ print(f"\n✅ Found {data['total_emails']} emails")
102
+ print(f"📤 From: {data['resolved_email']}")
103
+ print(f"📅 Period: {data['start_date']} to {data['end_date']}")
104
+
105
+ if data['emails']:
106
+ print(f"\n📧 Emails:")
107
+ for email in data['emails'][:10]: # Show first 10
108
+ print(self.pretty_print_email(email))
109
+
110
+ if len(data['emails']) > 10:
111
+ print(f"\n... and {len(data['emails']) - 10} more emails")
112
+ else:
113
+ print("\n📭 No emails found in this date range")
114
+
115
+ def show_mappings(self):
116
+ """Display all stored name-to-email mappings"""
117
+ try:
118
+ response = self.session.get(f"{API_BASE}/view_mappings")
119
+ if response.status_code == 200:
120
+ data = response.json()
121
+ mappings = data["mappings"]
122
+
123
+ print(f"\n📇 Stored Mappings ({len(mappings)}):")
124
+ if mappings:
125
+ for name, email in mappings.items():
126
+ print(f" 👤 {name} → 📧 {email}")
127
+ else:
128
+ print(" (No mappings stored)")
129
+ else:
130
+ print(f"❌ Failed to load mappings: {response.text}")
131
+ except Exception as e:
132
+ print(f"❌ Error: {e}")
133
+
134
+ def run(self):
135
+ """Main CLI loop"""
136
+ if not self.check_connection():
137
+ print("❌ Cannot connect to API server at http://127.0.0.1:8000")
138
+ print(" Make sure to run: uvicorn main:app --reload")
139
+ sys.exit(1)
140
+
141
+ print("✅ Connected to Email Query System")
142
+ print("💡 Try queries like:")
143
+ print(" • 'emails from john last week'")
144
+ print(" • 'show amazon emails from last month'")
145
+ print(" • 'get [email protected] emails yesterday'")
146
+ print("\n📋 Commands:")
147
+ print(" • 'mappings' - View stored name-to-email mappings")
148
+ print(" • 'quit' or Ctrl+C - Exit")
149
+ print("=" * 60)
150
+
151
+ while True:
152
+ try:
153
+ query = input("\n🗨️ You: ").strip()
154
+
155
+ if not query:
156
+ continue
157
+
158
+ if query.lower() in ['quit', 'exit', 'q']:
159
+ break
160
+ elif query.lower() in ['mappings', 'map', 'm']:
161
+ self.show_mappings()
162
+ elif query.lower() in ['help', 'h']:
163
+ print("\n💡 Examples:")
164
+ print(" • emails from amazon last 5 days")
165
+ print(" • show john smith emails this week")
166
+ print(" • get notifications from google yesterday")
167
+ else:
168
+ self.handle_query(query)
169
+
170
+ except KeyboardInterrupt:
171
+ break
172
+ except Exception as e:
173
+ print(f"❌ Unexpected error: {e}")
174
+
175
+ print("\n👋 Goodbye!")
176
+
177
+ def main():
178
+ """Entry point for CLI"""
179
+ cli = EmailQueryCLI()
180
+ cli.run()
181
+
182
+ if __name__ == "__main__":
183
+ main()
mcp/client/host.py DELETED
@@ -1,110 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- CLI host for the FastAPI-powered Swiggy server.
4
-
5
- Flow
6
- 1. Send natural-language query → /parse_query
7
- 2. If is_swiggy_query == True and dates are present → /get_orders
8
- 3. Pretty-print the result
9
- """
10
-
11
- import requests, sys
12
- from dateutil import parser as dtparse
13
-
14
- API_BASE = "http://127.0.0.1:8000"
15
-
16
- # ----------------------------------------------------------------------
17
- # Helpers
18
- # ----------------------------------------------------------------------
19
- def nice_date(dt_str: str | None) -> str:
20
- if not dt_str:
21
- return "??"
22
- return dtparse.parse(dt_str).strftime("%d %b %Y")
23
-
24
- def pretty_order(order: dict) -> str:
25
- if "error" in order:
26
- return f" - Email #{order['email_number']}: ❌ {order['error']}"
27
- head = (
28
- f"Restaurant : {order['restaurant_name']}\n"
29
- f"Date : {nice_date(order['order_date'])} {order['order_time']}\n"
30
- f"Total : ₹{order['total_price']:.0f}\n"
31
- "Items:"
32
- )
33
- items = "\n".join(
34
- f" • {it['quantity']} × {it['name']} – ₹{it['price']:.0f}"
35
- for it in order["items"]
36
- )
37
- return head + "\n" + items
38
-
39
- # ----------------------------------------------------------------------
40
- # Main REPL
41
- # ----------------------------------------------------------------------
42
- def main() -> None:
43
- # Quick health-check
44
- try:
45
- requests.get(f"{API_BASE}/docs").raise_for_status()
46
- except Exception as e:
47
- print("❌ Cannot reach FastAPI server:", e)
48
- sys.exit(1)
49
- print("✅ Connected. Type a Swiggy question (or Ctrl-C to quit).")
50
-
51
- while True:
52
- try:
53
- query = input("\n🗨️ You: ").strip()
54
- except (EOFError, KeyboardInterrupt):
55
- break
56
- if not query:
57
- continue
58
-
59
- # ── Stage 1: parse_query ────────────────────────────────────
60
- try:
61
- r = requests.post(f"{API_BASE}/parse_query", json={"query": query})
62
- r.raise_for_status()
63
- meta = r.json() # {is_swiggy_query, start_date, end_date, intent}
64
- except Exception as e:
65
- print("⚠️ Parse error:", e)
66
- print("🔎 Server:", r.text if 'r' in locals() else "no response")
67
- continue
68
-
69
- # Handle non-Swiggy or missing dates
70
- if not meta.get("is_swiggy_query"):
71
- print("🤷 That doesn’t look like a Swiggy order query.")
72
- continue
73
- if not meta.get("start_date") or not meta.get("end_date"):
74
- print("⚠️ Couldn’t find a full date range in your question.")
75
- continue
76
-
77
- print(f" ↳ Date range: {meta['start_date']} → {meta['end_date']}")
78
- print(f" ↳ Intent : {meta['intent']}")
79
-
80
- # ── Stage 2: get_orders ────────────────────────────────────
81
- try:
82
- r2 = requests.post(
83
- f"{API_BASE}/get_orders",
84
- json={
85
- "start_date": meta["start_date"],
86
- "end_date": meta["end_date"],
87
- },
88
- )
89
- r2.raise_for_status()
90
- orders = r2.json()
91
- except Exception as e:
92
- print("⚠️ Failed to fetch orders:", e)
93
- print("🔎 Server:", r2.text if 'r2' in locals() else "no response")
94
- continue
95
-
96
- # ── Output ────────────────────────────────────────────────
97
- if not orders:
98
- print("😕 No orders found for that range.")
99
- continue
100
-
101
- print("\n📦 Orders:")
102
- for o in orders:
103
- print(pretty_order(o))
104
- print("-" * 40)
105
-
106
- print("\n👋 Bye!")
107
-
108
- # ----------------------------------------------------------------------
109
- if __name__ == "__main__":
110
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mcp/server/db_schema.py DELETED
@@ -1,124 +0,0 @@
1
- # File: db_schema.py
2
- import sqlite3
3
-
4
- DB_NAME = "swiggy_orders.db"
5
-
6
-
7
- def init_db(db_path: str = DB_NAME) -> None:
8
- """
9
- Initialize the SQLite database with the necessary tables.
10
- """
11
- conn = sqlite3.connect(db_path)
12
- c = conn.cursor()
13
- # Orders metadata
14
- c.execute(
15
- """
16
- CREATE TABLE IF NOT EXISTS orders (
17
- id INTEGER PRIMARY KEY AUTOINCREMENT,
18
- email_number INTEGER,
19
- order_date TEXT,
20
- order_time TEXT,
21
- restaurant_name TEXT,
22
- delivery_address TEXT,
23
- total_price REAL
24
- )
25
- """
26
- )
27
- # Individual items per order
28
- c.execute(
29
- """
30
- CREATE TABLE IF NOT EXISTS order_items (
31
- id INTEGER PRIMARY KEY AUTOINCREMENT,
32
- order_id INTEGER,
33
- item_name TEXT,
34
- quantity INTEGER,
35
- price REAL,
36
- FOREIGN KEY(order_id) REFERENCES orders(id)
37
- )
38
- """
39
- )
40
- conn.commit()
41
- conn.close()
42
-
43
-
44
- def get_db_connection(db_path: str = DB_NAME) -> sqlite3.Connection:
45
- """Return a new connection to the database."""
46
- return sqlite3.connect(db_path)
47
-
48
-
49
- def get_orders_by_date_from_db(date_str: str) -> list[dict]:
50
- """
51
- Fetch all orders and their items for a given date from the database.
52
- """
53
- conn = get_db_connection()
54
- c = conn.cursor()
55
- c.execute(
56
- "SELECT id, email_number, order_time, restaurant_name, delivery_address, total_price"
57
- " FROM orders WHERE order_date = ?",
58
- (date_str,)
59
- )
60
- orders = []
61
- for order_id, email_number, order_time, restaurant_name, delivery_address, total_price in c.fetchall():
62
- # fetch items for this order
63
- c.execute(
64
- "SELECT item_name, quantity, price FROM order_items WHERE order_id = ?",
65
- (order_id,)
66
- )
67
- items = [
68
- {"name": name, "quantity": qty, "price": price}
69
- for name, qty, price in c.fetchall()
70
- ]
71
- orders.append({
72
- "email_number": email_number,
73
- "order_date": date_str,
74
- "order_time": order_time,
75
- "restaurant_name": restaurant_name,
76
- "delivery_address": delivery_address,
77
- "items": items,
78
- "total_price": total_price
79
- })
80
- conn.close()
81
- return orders
82
-
83
-
84
- def save_orders_to_db(date_str: str, orders: list[dict]) -> None:
85
- """
86
- Insert scraped orders and their items for a given date into the database.
87
- """
88
- conn = get_db_connection()
89
- c = conn.cursor()
90
- for order in orders:
91
- c.execute(
92
- """
93
- INSERT INTO orders
94
- (email_number, order_date, order_time, restaurant_name, delivery_address, total_price)
95
- VALUES (?, ?, ?, ?, ?, ?)
96
- """,
97
- (
98
- order["email_number"],
99
- date_str,
100
- order["order_time"],
101
- order["restaurant_name"],
102
- order["delivery_address"],
103
- order["total_price"]
104
- )
105
- )
106
- order_id = c.lastrowid
107
- for item in order.get("items", []):
108
- c.execute(
109
- """
110
- INSERT INTO order_items
111
- (order_id, item_name, quantity, price)
112
- VALUES (?, ?, ?, ?)
113
- """,
114
- (
115
- order_id,
116
- item["name"],
117
- item["quantity"],
118
- item["price"]
119
- )
120
- )
121
- conn.commit()
122
- conn.close()
123
-
124
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mcp/server/eval.txt DELETED
@@ -1,37 +0,0 @@
1
- EVALUATIONS
2
-
3
- able to differentiate between swiggy based queries or not
4
- able to break prompts into 2 instruction. First instruction will be extracting dates.
5
- second instructions will be analysing the data scrapped.
6
- able to extract dates
7
- able to extract the analysis:
8
-
9
- -How much non-veg did I order last week / between date X and date Y?
10
-
11
- -Counts and/or total rupees spent on non-veg dishes.
12
-
13
- -What was my total expense between date X and date Y?
14
-
15
- -What is my average daily spend on Swiggy (overall or for a given period)?
16
-
17
- -Which restaurant got the most orders (or the most money) in that period?
18
-
19
- -What single order cost me the most during that window?
20
-
21
- -Show a day-by-day spend chart between date X and date Y.
22
-
23
- -List every item I’ve ordered only once—my “one-hit wonders.”
24
-
25
- -How many unique cuisines did I try in the last month?
26
-
27
- -Compare veg vs. non-veg spend for the current calendar year.
28
-
29
- -When was my longest streak of days without ordering anything?
30
-
31
- -Identify any “late-night” orders placed after 11 p.m. this week.
32
-
33
- -Tell me my top three most-ordered dishes in the past six months.
34
-
35
- -Which new restaurant did I try most recently, and what did I order?
36
-
37
- -Forecast next month’s spend based on my last three-month trend.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mcp/server/main.py DELETED
@@ -1,24 +0,0 @@
1
- # File: main.py
2
- from fastapi import FastAPI
3
- from contextlib import asynccontextmanager
4
- from routes import router
5
- from db_schema import init_db
6
-
7
- @asynccontextmanager
8
- async def lifespan(app: FastAPI):
9
- print("🚀 Server is starting up...")
10
- # Ensure SQLite tables exist before handling requests
11
- init_db()
12
- yield
13
- print("🧹 Server is shutting down... Cleaned up!")
14
-
15
- app = FastAPI(
16
- title="Swiggy Email API",
17
- description="Extract Swiggy orders from Gmail",
18
- version="1.0.0",
19
- lifespan=lifespan
20
- )
21
-
22
- app.include_router(router)
23
-
24
- # Run with: uvicorn main:app --reload
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mcp/server/routes.py DELETED
@@ -1,167 +0,0 @@
1
- from fastapi import APIRouter, HTTPException
2
- from pydantic import BaseModel
3
- from swiggy_scraper import fetch_swiggy_orders
4
- from datetime import datetime
5
- from openai import OpenAI
6
- import os, json
7
-
8
- router = APIRouter()
9
- client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
10
-
11
- class QueryInput(BaseModel):
12
- query: str
13
-
14
- class DateRange(BaseModel):
15
- start_date: str
16
- end_date: str
17
-
18
- # @router.post("/parse_query")
19
- # def parse_query_llm(input: QueryInput):
20
-
21
- # print("\ninput query:")
22
- # print(input)
23
-
24
- # today_str = datetime.today().strftime("%d-%b-%Y")
25
- # system = (
26
- # f"You are a date range extractor.\n"
27
- # f"Today is {today_str}.\n"
28
- # "Extract start_date and end_date in 'DD-MMM-YYYY' format.\n"
29
- # "Respond with:\n"
30
- # "Output ONLY a valid JSON object like:\n"
31
- # '{ "start_date": "17-May-2025", "end_date": "18-May-2025" }\n'
32
- # 'no extra commentry needed.'
33
- # )
34
- # try:
35
- # rsp = client.chat.completions.create(
36
- # model="gpt-4o-mini",
37
- # temperature=0,
38
- # messages=[
39
- # {"role": "system", "content": system},
40
- # {"role": "user", "content": input.query},
41
- # ]
42
- # )
43
- # result = json.loads(rsp.choices[0].message.content.strip())
44
- # if "start_date" not in result or "end_date" not in result:
45
- # raise ValueError("Invalid response format")
46
- # print("results:", result)
47
- # return result
48
- # except Exception as e:
49
- # raise HTTPException(status_code=400, detail=str(e))
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
- def _llm(messages, model="gpt-4o-mini", temperature=0):
58
- rsp = client.chat.completions.create(
59
- model=model,
60
- temperature=temperature,
61
- messages=messages,
62
- )
63
- return rsp.choices[0].message.content.strip()
64
-
65
- # ---------- Stage 1: classify + extract dates --------------------------
66
-
67
- def _extract_scope(user_query: str):
68
- today_str = datetime.today().strftime("%d-%b-%Y")
69
-
70
- sys_prompt = f"""
71
- Today is {today_str}.
72
- You are a SCOPING assistant: decide if the user's text is about Swiggy food orders,
73
- extract ONE date range, and keep the leftover words.
74
-
75
- Return ONLY valid JSON like:
76
- {{
77
- "is_swiggy_query": true,
78
- "start_date": "15-May-2025",
79
- "end_date": "20-May-2025",
80
- "remainder": "non veg expense"
81
- }}
82
-
83
- Rules:
84
- • Accept natural phrases (“last week”, “since 1 May”).
85
- • If no dates → start_date & end_date = null.
86
- • If not Swiggy related → is_swiggy_query=false and remainder is full original text.
87
- • Do NOT invent a remainder; it is literally whatever words follow the date phrase(s).
88
- """
89
- raw = _llm(
90
- [
91
- {"role": "system", "content": sys_prompt},
92
- {"role": "user", "content": user_query}
93
- ]
94
- )
95
- return json.loads(raw)
96
-
97
- # ---------- Stage 2: shrink “remainder” into an intent -----------------
98
-
99
- def _extract_intent(remainder: str):
100
- sys_prompt = """
101
- You are an INTENT classifier for Swiggy-order analytics.
102
- Map the sentence into one concise snake_case intent.
103
- Allowed intents (extendable):
104
-
105
- • calculate_expense
106
- • list_orders
107
- • list_items
108
- • list_nonveg_items
109
- • list_veg_items
110
- • count_orders
111
- • unknown
112
-
113
- Return JSON: { "intent": "calculate_expense" }
114
- If unsure choose "unknown".
115
- """
116
- raw = _llm(
117
- [
118
- {"role": "system", "content": sys_prompt},
119
- {"role": "user", "content": remainder.strip()}
120
- ]
121
- )
122
- return json.loads(raw)["intent"]
123
-
124
- # ---------- FastAPI route ----------------------------------------------
125
-
126
- @router.post("/parse_query")
127
- def parse_query_llm(input: QueryInput):
128
- try:
129
- scope = _extract_scope(input.query)
130
- print("scope")
131
- print(scope)
132
- # If it is a Swiggy query, classify intent; else, intent = "unrelated"
133
- if scope.get("is_swiggy_query", False):
134
- intent = _extract_intent(scope.get("remainder", ""))
135
- else:
136
- intent = "unrelated"
137
-
138
- result = {
139
- "is_swiggy_query": scope["is_swiggy_query"],
140
- "start_date": scope["start_date"],
141
- "end_date": scope["end_date"],
142
- "intent": intent
143
- }
144
-
145
-
146
- print("result")
147
- print(result)
148
-
149
- return result
150
-
151
- except Exception as e:
152
- raise HTTPException(status_code=400, detail=str(e))
153
-
154
-
155
-
156
-
157
-
158
-
159
-
160
-
161
- @router.post("/get_orders")
162
- def get_orders(range: DateRange):
163
- try:
164
- orders = fetch_swiggy_orders(range.start_date, range.end_date)
165
- return orders
166
- except Exception as e:
167
- raise HTTPException(status_code=500, detail=str(e))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mcp/server/swiggy_cache.json DELETED
@@ -1,1379 +0,0 @@
1
- {
2
- "2025-05-17": [
3
- {
4
- "email_number": 1,
5
- "order_date": "17-May-2025",
6
- "order_time": "11:00:08",
7
- "restaurant_name": "IDC Kitchen",
8
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
9
- "items": [
10
- {
11
- "name": "Thatte Idli",
12
- "quantity": 1,
13
- "price": 59
14
- },
15
- {
16
- "name": "Idly 2 Pc",
17
- "quantity": 1,
18
- "price": 59
19
- },
20
- {
21
- "name": "Vada (1 Pc)",
22
- "quantity": 3,
23
- "price": 174
24
- }
25
- ],
26
- "total_price": 330
27
- },
28
- {
29
- "email_number": 2,
30
- "order_date": "17-May-2025",
31
- "order_time": "17:02:59",
32
- "restaurant_name": "Suryawanshi",
33
- "delivery_address": "Shobhit\n2C, Orchard Green Apartment\n2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
34
- "items": [
35
- {
36
- "name": "Vada Pav (twin)",
37
- "quantity": 1,
38
- "price": 95
39
- },
40
- {
41
- "name": "Kande Bhaji",
42
- "quantity": 1,
43
- "price": 160
44
- }
45
- ],
46
- "total_price": 300
47
- },
48
- {
49
- "email_number": 3,
50
- "order_date": "17-May-2025",
51
- "order_time": "20:25:39",
52
- "restaurant_name": "Meghana Foods",
53
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
54
- "items": [
55
- {
56
- "name": "Extra Aloo 4 Pcs",
57
- "quantity": 1,
58
- "price": 45
59
- },
60
- {
61
- "name": "Chicken Boneless Biryani",
62
- "quantity": 1,
63
- "price": 360
64
- },
65
- {
66
- "name": "Lemon Chicken",
67
- "quantity": 1,
68
- "price": 360
69
- },
70
- {
71
- "name": "Veg Manchurian Biryani",
72
- "quantity": 1,
73
- "price": 360
74
- }
75
- ],
76
- "total_price": 1240
77
- }
78
- ],
79
- "2025-05-19": [
80
- {
81
- "email_number": 1,
82
- "order_date": "19-May-2025",
83
- "order_time": "22:28:08",
84
- "restaurant_name": "Swiggy Instamart",
85
- "delivery_address": "2C, Orchard Green Apartment 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
86
- "items": [
87
- {
88
- "name": "Safal Frozen Green Peas (Matar)",
89
- "quantity": 1,
90
- "price": 110
91
- },
92
- {
93
- "name": "NOTO Strawberry Raspberry Sugar Free Popsicle Ice Cream",
94
- "quantity": 4,
95
- "price": 500
96
- },
97
- {
98
- "name": "Baby Lady's Finger (Bendekaayi)",
99
- "quantity": 2,
100
- "price": 32
101
- },
102
- {
103
- "name": "Whisper Ultra Skin Love Soft 30 Xl+ Sanitary Pads, Cottony Soft",
104
- "quantity": 1,
105
- "price": 323
106
- },
107
- {
108
- "name": "Akshayakalpa Artisanal Organic Set Curd",
109
- "quantity": 1,
110
- "price": 145
111
- },
112
- {
113
- "name": "Akshayakalpa Organic Malai Paneer",
114
- "quantity": 1,
115
- "price": 119
116
- },
117
- {
118
- "name": "Aashirvaad Superior MP Atta",
119
- "quantity": 2,
120
- "price": 146
121
- },
122
- {
123
- "name": "NOTO Kala Jamun Sugar Free Popsicle Ice Cream",
124
- "quantity": 2,
125
- "price": 250
126
- },
127
- {
128
- "name": "Royal Gala Apple (Sebu)",
129
- "quantity": 2,
130
- "price": 356
131
- }
132
- ],
133
- "total_price": 1564
134
- }
135
- ],
136
- "2025-05-01": [
137
- {
138
- "email_number": 1,
139
- "order_date": "01-May-2025",
140
- "order_time": "11:36:15",
141
- "restaurant_name": "Starbucks Coffee",
142
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
143
- "items": [
144
- {
145
- "name": "Caffe Americano",
146
- "quantity": 2,
147
- "price": 710
148
- }
149
- ],
150
- "total_price": 647
151
- },
152
- {
153
- "email_number": 2,
154
- "order_date": "01-May-2025",
155
- "order_time": "18:34:08",
156
- "restaurant_name": "Chaayos Chai+Snacks=Relax",
157
- "delivery_address": "Shobhit\n2C, Orchard Green Apartment\n2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
158
- "items": [
159
- {
160
- "name": "Vada Pav",
161
- "quantity": 2,
162
- "price": 238
163
- },
164
- {
165
- "name": "Desi Chai",
166
- "quantity": 1,
167
- "price": 219
168
- },
169
- {
170
- "name": "Samosa(2 pc)",
171
- "quantity": 1,
172
- "price": 90
173
- }
174
- ],
175
- "total_price": 528
176
- },
177
- {
178
- "email_number": 3,
179
- "order_date": "01-May-2025",
180
- "order_time": "21:28:12",
181
- "restaurant_name": "Lavonne Cafe",
182
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
183
- "items": [
184
- {
185
- "name": "Baguette",
186
- "quantity": 1,
187
- "price": 190.48
188
- }
189
- ],
190
- "total_price": 278
191
- }
192
- ],
193
- "2025-05-02": [
194
- {
195
- "email_number": 1,
196
- "order_date": "02-May-2025",
197
- "order_time": "11:13:38",
198
- "restaurant_name": "Starbucks Coffee",
199
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
200
- "items": [
201
- {
202
- "name": "Caffe Americano",
203
- "quantity": 1,
204
- "price": 315
205
- },
206
- {
207
- "name": "Caffe Americano",
208
- "quantity": 1,
209
- "price": 355
210
- }
211
- ],
212
- "total_price": 605
213
- },
214
- {
215
- "email_number": 2,
216
- "order_date": "02-May-2025",
217
- "order_time": "14:43:19",
218
- "restaurant_name": "Harvest Salad Co",
219
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
220
- "items": [
221
- {
222
- "name": "Hummus And Chipotle Chicken Wrap",
223
- "quantity": 2,
224
- "price": 498
225
- },
226
- {
227
- "name": "Mediterranean Bowl (Veg)",
228
- "quantity": 1,
229
- "price": 299
230
- }
231
- ],
232
- "total_price": 899
233
- },
234
- {
235
- "email_number": 3,
236
- "order_date": "02-May-2025",
237
- "order_time": "21:10:20",
238
- "restaurant_name": "Swiggy Instamart",
239
- "delivery_address": "2C, Orchard Green Apartment 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
240
- "items": [
241
- {
242
- "name": "Classic Ice Burst",
243
- "quantity": 1,
244
- "price": 170
245
- }
246
- ],
247
- "total_price": 222
248
- },
249
- {
250
- "email_number": 4,
251
- "order_date": "02-May-2025",
252
- "order_time": "22:01:35",
253
- "restaurant_name": "Dhaba Estd 1986 Delhi",
254
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
255
- "items": [
256
- {
257
- "name": "Non Vegetarian Platter ( 12 Pcs)",
258
- "quantity": 1,
259
- "price": 1249
260
- },
261
- {
262
- "name": "Butter Naan",
263
- "quantity": 2,
264
- "price": 198
265
- },
266
- {
267
- "name": "Dhabe Di Roti",
268
- "quantity": 2,
269
- "price": 238
270
- },
271
- {
272
- "name": "Laal Mirchi Parantha",
273
- "quantity": 1,
274
- "price": 109
275
- },
276
- {
277
- "name": "Handi Murgh",
278
- "quantity": 1,
279
- "price": 629
280
- }
281
- ],
282
- "total_price": 2006
283
- }
284
- ],
285
- "2025-05-03": [
286
- {
287
- "email_number": 1,
288
- "order_date": "03-May-2025",
289
- "order_time": "09:50:51",
290
- "restaurant_name": "Starbucks Coffee",
291
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
292
- "items": [
293
- {
294
- "name": "Cold Brew Black",
295
- "quantity": 1,
296
- "price": 410
297
- },
298
- {
299
- "name": "Caffe Americano.",
300
- "quantity": 1,
301
- "price": 315
302
- }
303
- ],
304
- "total_price": 691
305
- },
306
- {
307
- "email_number": 2,
308
- "order_date": "03-May-2025",
309
- "order_time": "15:06:18",
310
- "restaurant_name": "Copper + Cloves",
311
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
312
- "items": [
313
- {
314
- "name": "Asian Peanut Salad",
315
- "quantity": 1,
316
- "price": 500
317
- },
318
- {
319
- "name": "Tofu",
320
- "quantity": 1,
321
- "price": 100
322
- }
323
- ],
324
- "total_price": 432
325
- },
326
- {
327
- "email_number": 3,
328
- "order_date": "03-May-2025",
329
- "order_time": "21:32:47",
330
- "restaurant_name": "Shiro",
331
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
332
- "items": [
333
- {
334
- "name": "Super Crunch (8 pcs)",
335
- "quantity": 1,
336
- "price": 695
337
- },
338
- {
339
- "name": "Bulgogi Chicken Spring Rolls (6 pcs)",
340
- "quantity": 1,
341
- "price": 595
342
- },
343
- {
344
- "name": "Cantonese Chicken Wonton (6 pcs)",
345
- "quantity": 1,
346
- "price": 410
347
- },
348
- {
349
- "name": "Smoky Pork Gyoza (4 pcs)",
350
- "quantity": 1,
351
- "price": 495
352
- },
353
- {
354
- "name": "Spicy Salmon Negi (8 pcs)",
355
- "quantity": 1,
356
- "price": 670
357
- }
358
- ],
359
- "total_price": 2600
360
- }
361
- ],
362
- "2025-05-04": [
363
- {
364
- "email_number": 1,
365
- "order_date": "04-May-2025",
366
- "order_time": "09:54:22",
367
- "restaurant_name": "IDC Kitchen",
368
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
369
- "items": [
370
- {
371
- "name": "Masala Dosa",
372
- "quantity": 1,
373
- "price": 140
374
- },
375
- {
376
- "name": "Idly 2 Pc",
377
- "quantity": 1,
378
- "price": 59
379
- },
380
- {
381
- "name": "Thatte Idli",
382
- "quantity": 1,
383
- "price": 59
384
- },
385
- {
386
- "name": "Vada (1 Pc)",
387
- "quantity": 1,
388
- "price": 58
389
- }
390
- ],
391
- "total_price": 356
392
- },
393
- {
394
- "email_number": 2,
395
- "order_date": "04-May-2025",
396
- "order_time": "10:21:33",
397
- "restaurant_name": "Starbucks Coffee",
398
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
399
- "items": [
400
- {
401
- "name": "Caffe Americano",
402
- "quantity": 1,
403
- "price": 315
404
- },
405
- {
406
- "name": "Caffe Americano",
407
- "quantity": 1,
408
- "price": 355
409
- }
410
- ],
411
- "total_price": 694
412
- }
413
- ],
414
- "2025-05-05": [
415
- {
416
- "email_number": 1,
417
- "order_date": "05-May-2025",
418
- "order_time": "09:23:24",
419
- "restaurant_name": "Starbucks Coffee",
420
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
421
- "items": [
422
- {
423
- "name": "Caffe Americano",
424
- "quantity": 1,
425
- "price": 315
426
- },
427
- {
428
- "name": "Caffe Americano",
429
- "quantity": 1,
430
- "price": 355
431
- }
432
- ],
433
- "total_price": 694
434
- },
435
- {
436
- "email_number": 2,
437
- "order_date": "05-May-2025",
438
- "order_time": "13:58:29",
439
- "restaurant_name": "Maverick & Farmer Coffee",
440
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
441
- "items": [
442
- {
443
- "name": "Cold Brew Latte",
444
- "quantity": 1,
445
- "price": 300
446
- },
447
- {
448
- "name": "Smoked Tandoori Chicken",
449
- "quantity": 1,
450
- "price": 450
451
- }
452
- ],
453
- "total_price": 730
454
- },
455
- {
456
- "email_number": 3,
457
- "order_date": "05-May-2025",
458
- "order_time": "14:42:09",
459
- "restaurant_name": "Magnolia Bakery",
460
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
461
- "items": [
462
- {
463
- "name": "CLASSIC TRES LECHES",
464
- "quantity": 1,
465
- "price": 410
466
- }
467
- ],
468
- "total_price": 538
469
- },
470
- {
471
- "email_number": 4,
472
- "order_date": "05-May-2025",
473
- "order_time": "21:09:39",
474
- "restaurant_name": "Hyderabad Biryaani House",
475
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
476
- "items": [
477
- {
478
- "name": "Mutton Biryani Family Pack",
479
- "quantity": 1,
480
- "price": 749
481
- }
482
- ],
483
- "total_price": 806
484
- }
485
- ],
486
- "2025-05-06": [
487
- {
488
- "email_number": 1,
489
- "order_date": "06-May-2025",
490
- "order_time": "09:58:07",
491
- "restaurant_name": "Swiggy Instamart",
492
- "delivery_address": "2C, Orchard Green Apartment 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
493
- "items": [
494
- {
495
- "name": "Yellaki Banana (Baalehannu)",
496
- "quantity": 1,
497
- "price": 59
498
- },
499
- {
500
- "name": "Robusta Banana (Pachha Baalehannu)",
501
- "quantity": 1,
502
- "price": 30
503
- },
504
- {
505
- "name": "Eggoz Farm Fresh High Protein White Eggs Box",
506
- "quantity": 1,
507
- "price": 325
508
- },
509
- {
510
- "name": "Amul Processed Cheese Slices",
511
- "quantity": 1,
512
- "price": 145
513
- },
514
- {
515
- "name": "NOTO Orange Sugar Free Popsicle Ice Cream",
516
- "quantity": 2,
517
- "price": 157.5
518
- },
519
- {
520
- "name": "Rocket Leaves (Arugula)",
521
- "quantity": 1,
522
- "price": 54
523
- },
524
- {
525
- "name": "Royal Gala Apple (Sebu)",
526
- "quantity": 2,
527
- "price": 254.6
528
- },
529
- {
530
- "name": "NOTO Kala Jamun Sugar Free Popsicle Ice Cream",
531
- "quantity": 2,
532
- "price": 132.5
533
- },
534
- {
535
- "name": "Imported Avocado - Tanzania",
536
- "quantity": 1,
537
- "price": 75
538
- },
539
- {
540
- "name": "Ratnagiri Alphonso Mango (Hapus)",
541
- "quantity": 1,
542
- "price": 415
543
- },
544
- {
545
- "name": "Indian Blueberries",
546
- "quantity": 1,
547
- "price": 199
548
- },
549
- {
550
- "name": "Flyer Dil Foods",
551
- "quantity": 1,
552
- "price": 0
553
- },
554
- {
555
- "name": "Premium Guava (Thai)",
556
- "quantity": 1,
557
- "price": 71
558
- },
559
- {
560
- "name": "Lettuce Mix Salad",
561
- "quantity": 2,
562
- "price": 120
563
- }
564
- ],
565
- "total_price": 2049
566
- },
567
- {
568
- "email_number": 2,
569
- "order_date": "06-May-2025",
570
- "order_time": "10:51:28",
571
- "restaurant_name": "Starbucks Coffee",
572
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
573
- "items": [
574
- {
575
- "name": "Caffe Americano",
576
- "quantity": 1,
577
- "price": 355
578
- },
579
- {
580
- "name": "Caffe Americano",
581
- "quantity": 1,
582
- "price": 315
583
- }
584
- ],
585
- "total_price": 694
586
- },
587
- {
588
- "email_number": 3,
589
- "order_date": "06-May-2025",
590
- "order_time": "11:06:59",
591
- "restaurant_name": "Yogisthaan",
592
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
593
- "items": [
594
- {
595
- "name": "Tapioca (sabu Dana) Khichadi",
596
- "quantity": 1,
597
- "price": 252
598
- },
599
- {
600
- "name": "Sattu Paratha",
601
- "quantity": 1,
602
- "price": 288
603
- }
604
- ],
605
- "total_price": 537
606
- },
607
- {
608
- "email_number": 4,
609
- "order_date": "06-May-2025",
610
- "order_time": "15:05:22",
611
- "restaurant_name": "Sweet Karam Coffee",
612
- "delivery_address": "2C, Orchard Green Apartment 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
613
- "items": [
614
- {
615
- "name": "Sweet Karam Coffee Tapioca Chips (Kappa) - No Palm Oil",
616
- "quantity": 1,
617
- "price": 65
618
- },
619
- {
620
- "name": "Sweet Karam Coffee Special Madras Mixture (No Palm Oil)",
621
- "quantity": 1,
622
- "price": 90
623
- },
624
- {
625
- "name": "Sweet Karam Coffee Peanut Chikki Bites (No White Sugar, No Liquid Glucose)",
626
- "quantity": 1,
627
- "price": 87
628
- },
629
- {
630
- "name": "Mother's Recipe Potato Masala Papad",
631
- "quantity": 4,
632
- "price": 126.64
633
- },
634
- {
635
- "name": "Sweet Karam Coffee Kerala Nendran Banana Chips",
636
- "quantity": 1,
637
- "price": 87.12
638
- },
639
- {
640
- "name": "Iyer's Rice Papad Buy 1 Get 1 (inside one pack)",
641
- "quantity": 1,
642
- "price": 64
643
- },
644
- {
645
- "name": "Ginger kombucha (Low cal, Low sugar)",
646
- "quantity": 4,
647
- "price": 368.28
648
- }
649
- ],
650
- "total_price": 899
651
- },
652
- {
653
- "email_number": 5,
654
- "order_date": "06-May-2025",
655
- "order_time": "22:36:46",
656
- "restaurant_name": "Misu",
657
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India.",
658
- "items": [
659
- {
660
- "name": "Spicy Chilli Basil Noodles Non-veg",
661
- "quantity": 1,
662
- "price": 465
663
- },
664
- {
665
- "name": "Vietnamese Pho Chicken",
666
- "quantity": 1,
667
- "price": 305
668
- },
669
- {
670
- "name": "Sour & Spicy Dumplings Chicken (6 Pcs)",
671
- "quantity": 1,
672
- "price": 405
673
- }
674
- ],
675
- "total_price": 1117
676
- }
677
- ],
678
- "2025-05-07": [
679
- {
680
- "email_number": 1,
681
- "order_date": "07-May-2025",
682
- "order_time": "13:26:32",
683
- "restaurant_name": "Kale - A Salad Symphony",
684
- "delivery_address": "Shobhit\n2nd Floor\nKariyammana Agrahara Road, Marathahalli, Bengaluru, Karnataka 560037, India. (Divyasree Technopolis)",
685
- "items": [
686
- {
687
- "name": "Thai Chicken Bowl (nutrients & Vitamin B12)",
688
- "quantity": 1,
689
- "price": 425
690
- },
691
- {
692
- "name": "Green Protein Smoothie",
693
- "quantity": 1,
694
- "price": 250
695
- }
696
- ],
697
- "total_price": 693
698
- },
699
- {
700
- "email_number": 2,
701
- "order_date": "07-May-2025",
702
- "order_time": "13:53:43",
703
- "restaurant_name": "Chakum Chukum",
704
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
705
- "items": [
706
- {
707
- "name": "Chicken Tikka Roll",
708
- "quantity": 1,
709
- "price": 237.15
710
- },
711
- {
712
- "name": "Kasundi Paneer Roll",
713
- "quantity": 1,
714
- "price": 275.24
715
- }
716
- ],
717
- "total_price": 518
718
- },
719
- {
720
- "email_number": 3,
721
- "order_date": "07-May-2025",
722
- "order_time": "20:50:27",
723
- "restaurant_name": "Lavonne Cafe",
724
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
725
- "items": [
726
- {
727
- "name": "Sourdough Bread Plain",
728
- "quantity": 1,
729
- "price": 219.05
730
- }
731
- ],
732
- "total_price": 41
733
- },
734
- {
735
- "email_number": 4,
736
- "order_date": "07-May-2025",
737
- "order_time": "21:51:42",
738
- "restaurant_name": "Basco And Fry",
739
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
740
- "items": [
741
- {
742
- "name": "Truffle Shroom Burger",
743
- "quantity": 1,
744
- "price": 365
745
- },
746
- {
747
- "name": "Peri Peri Wings",
748
- "quantity": 1,
749
- "price": 425
750
- },
751
- {
752
- "name": "Chicken Katsu Burger",
753
- "quantity": 1,
754
- "price": 365
755
- }
756
- ],
757
- "total_price": 1100
758
- }
759
- ],
760
- "2025-05-08": [
761
- {
762
- "email_number": 1,
763
- "order_date": "08-May-2025",
764
- "order_time": "13:04:12",
765
- "restaurant_name": "NATRAJ Chole bhature",
766
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
767
- "items": [
768
- {
769
- "name": "Chole Bhature(full Plate)",
770
- "quantity": 1,
771
- "price": 225
772
- },
773
- {
774
- "name": "Samosa(1pc)",
775
- "quantity": 1,
776
- "price": 45
777
- }
778
- ],
779
- "total_price": 310
780
- },
781
- {
782
- "email_number": 2,
783
- "order_date": "08-May-2025",
784
- "order_time": "14:27:04",
785
- "restaurant_name": "Salad Days",
786
- "delivery_address": "2nd Floor, Kariyammana Agrahara Road, Marathahalli, Bengaluru, Karnataka 560037, India. (Divyasree Technopolis)",
787
- "items": [
788
- {
789
- "name": "Asian Chicken, Egg & Soba Noodle Salad",
790
- "quantity": 1,
791
- "price": 379
792
- },
793
- {
794
- "name": "Green Pressed Juice",
795
- "quantity": 1,
796
- "price": 199
797
- }
798
- ],
799
- "total_price": 655
800
- },
801
- {
802
- "email_number": 3,
803
- "order_date": "08-May-2025",
804
- "order_time": "22:47:20",
805
- "restaurant_name": "Mahesh Lunch Home",
806
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
807
- "items": [
808
- {
809
- "name": "Appam",
810
- "quantity": 2,
811
- "price": 60
812
- },
813
- {
814
- "name": "Chicken Ghee Roast",
815
- "quantity": 1,
816
- "price": 460
817
- },
818
- {
819
- "name": "Butter Roti",
820
- "quantity": 2,
821
- "price": 80
822
- },
823
- {
824
- "name": "Chicken Manglorean",
825
- "quantity": 1,
826
- "price": 405
827
- },
828
- {
829
- "name": "Neer Dosa (4 Pcs)",
830
- "quantity": 1,
831
- "price": 80
832
- },
833
- {
834
- "name": "Dal Fry",
835
- "quantity": 1,
836
- "price": 210
837
- }
838
- ],
839
- "total_price": 1267
840
- },
841
- {
842
- "email_number": 4,
843
- "order_date": "08-May-2025",
844
- "order_time": "23:41:54",
845
- "restaurant_name": "Swiggy Instamart",
846
- "delivery_address": "2C, Orchard Green Apartment 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
847
- "items": [
848
- {
849
- "name": "NOTO Strawberry Raspberry Sugar Free Popsicle Ice Cream",
850
- "quantity": 4,
851
- "price": 325
852
- },
853
- {
854
- "name": "NOTO Orange Sugar Free Popsicle Ice Cream",
855
- "quantity": 2,
856
- "price": 162.5
857
- }
858
- ],
859
- "total_price": 498
860
- }
861
- ],
862
- "2025-05-09": [
863
- {
864
- "email_number": 1,
865
- "order_date": "09-May-2025",
866
- "order_time": "15:22:57",
867
- "restaurant_name": "Kale - A Salad Symphony",
868
- "delivery_address": "Shobhit\n2nd Floor\nKariyammana Agrahara Road, Marathahalli, Bengaluru, Karnataka 560037, India. (Divyasree Technopolis)",
869
- "items": [
870
- {
871
- "name": "Thai Chicken Bowl (nutrients & Vitamin B12)",
872
- "quantity": 1,
873
- "price": 425
874
- },
875
- {
876
- "name": "Green Protein Smoothie",
877
- "quantity": 1,
878
- "price": 250
879
- }
880
- ],
881
- "total_price": 693
882
- },
883
- {
884
- "email_number": 2,
885
- "order_date": "09-May-2025",
886
- "order_time": "16:25:50",
887
- "restaurant_name": "Swiggy Instamart",
888
- "delivery_address": "2C, Orchard Green Apartment 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
889
- "items": [
890
- {
891
- "name": "Kodai Parmesan Cheese",
892
- "quantity": 1,
893
- "price": 475
894
- }
895
- ],
896
- "total_price": 487
897
- }
898
- ],
899
- "2025-05-10": [
900
- {
901
- "email_number": 1,
902
- "order_date": "10-May-2025",
903
- "order_time": "13:34:39",
904
- "restaurant_name": "Swiggy Instamart",
905
- "delivery_address": "2C, Orchard Green Apartment 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
906
- "items": [
907
- {
908
- "name": "Gooseberry (Nellikaayi)",
909
- "quantity": 1,
910
- "price": 39
911
- },
912
- {
913
- "name": "Fresh Turmeric",
914
- "quantity": 2,
915
- "price": 42
916
- },
917
- {
918
- "name": "Licious Chicken Curry Cut (Large Pieces) - Skinless",
919
- "quantity": 1,
920
- "price": 165
921
- },
922
- {
923
- "name": "White Radish (Moolangi)",
924
- "quantity": 2,
925
- "price": 30.6
926
- },
927
- {
928
- "name": "English Cucumber (Sowthekaayi)",
929
- "quantity": 2,
930
- "price": 65.8
931
- },
932
- {
933
- "name": "Robusta Banana (Pachha Baalehannu)",
934
- "quantity": 1,
935
- "price": 44
936
- },
937
- {
938
- "name": "Curry Leaves (Karibevu)",
939
- "quantity": 1,
940
- "price": 11
941
- },
942
- {
943
- "name": "Green Chilli (Hasiru Menasinakaayi)",
944
- "quantity": 1,
945
- "price": 12
946
- },
947
- {
948
- "name": "Coriander - Without Roots (Kotthambari)",
949
- "quantity": 1,
950
- "price": 18
951
- },
952
- {
953
- "name": "Ginger (Shunti)",
954
- "quantity": 1,
955
- "price": 16
956
- },
957
- {
958
- "name": "Premium Guava (Thai)",
959
- "quantity": 2,
960
- "price": 131.4
961
- },
962
- {
963
- "name": "Royal Gala Apple (Sebu)",
964
- "quantity": 2,
965
- "price": 275
966
- }
967
- ],
968
- "total_price": 862
969
- },
970
- {
971
- "email_number": 2,
972
- "order_date": "10-May-2025",
973
- "order_time": "17:23:45",
974
- "restaurant_name": "Irani Std. Tea",
975
- "delivery_address": "Swiggy,Tower D, 9th Floor, IBC Knowledge Park, Bannerghatta Road, Bangalore - 560029",
976
- "items": [],
977
- "total_price": 291
978
- },
979
- {
980
- "email_number": 3,
981
- "order_date": "10-May-2025",
982
- "order_time": "18:05:00",
983
- "restaurant_name": "Irani Std. Tea",
984
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India",
985
- "items": [
986
- {
987
- "name": "Irani Ginger Chai",
988
- "quantity": 1,
989
- "price": 219
990
- },
991
- {
992
- "name": "Osmania Biscuits 100 Grams",
993
- "quantity": 1,
994
- "price": 100
995
- },
996
- {
997
- "name": "Bun Maska",
998
- "quantity": 2,
999
- "price": 158
1000
- }
1001
- ],
1002
- "total_price": 399
1003
- }
1004
- ],
1005
- "2025-05-11": [
1006
- {
1007
- "email_number": 1,
1008
- "order_date": "11-May-2025",
1009
- "order_time": "12:36:17",
1010
- "restaurant_name": "Anand Sweets & Savouries",
1011
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India.",
1012
- "items": [
1013
- {
1014
- "name": "Shahi Tohfa Dry Fruits 750 Gms",
1015
- "quantity": 1,
1016
- "price": 1022.32
1017
- }
1018
- ],
1019
- "total_price": 1167
1020
- },
1021
- {
1022
- "email_number": 2,
1023
- "order_date": "11-May-2025",
1024
- "order_time": "21:17:18",
1025
- "restaurant_name": "Hotel Empire",
1026
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1027
- "items": [
1028
- {
1029
- "name": "Paneer Butter Masala",
1030
- "quantity": 1,
1031
- "price": 252
1032
- },
1033
- {
1034
- "name": "Kerala Parotta",
1035
- "quantity": 1,
1036
- "price": 39
1037
- },
1038
- {
1039
- "name": "Coin Parotta",
1040
- "quantity": 2,
1041
- "price": 64
1042
- },
1043
- {
1044
- "name": "Dal Fry",
1045
- "quantity": 1,
1046
- "price": 137
1047
- },
1048
- {
1049
- "name": "Ghee Rice",
1050
- "quantity": 1,
1051
- "price": 110
1052
- },
1053
- {
1054
- "name": "Malabar Parotta",
1055
- "quantity": 2,
1056
- "price": 70
1057
- }
1058
- ],
1059
- "total_price": 749
1060
- }
1061
- ],
1062
- "2025-05-12": [
1063
- {
1064
- "email_number": 1,
1065
- "order_date": "12-May-2025",
1066
- "order_time": "22:12:42",
1067
- "restaurant_name": "Swiggy Instamart",
1068
- "delivery_address": "2C, Orchard Green Apartment 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1069
- "items": [
1070
- {
1071
- "name": "NOTO Strawberry Raspberry Sugar Free Popsicle Ice Cream",
1072
- "quantity": 4,
1073
- "price": 275
1074
- },
1075
- {
1076
- "name": "NOTO Orange Sugar Free Popsicle Ice Cream",
1077
- "quantity": 2,
1078
- "price": 137.5
1079
- }
1080
- ],
1081
- "total_price": 423
1082
- }
1083
- ],
1084
- "2025-05-13": [],
1085
- "2025-05-14": [
1086
- {
1087
- "email_number": 1,
1088
- "order_date": "14-May-2025",
1089
- "order_time": "14:14:14",
1090
- "restaurant_name": "Swiggy Instamart",
1091
- "delivery_address": "2C, Orchard Green Apartment 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1092
- "items": [
1093
- {
1094
- "name": "Robusta Banana (Pachha Baalehannu)",
1095
- "quantity": 1,
1096
- "price": 42
1097
- },
1098
- {
1099
- "name": "Coriander - Without Roots (Kotthambari)",
1100
- "quantity": 1,
1101
- "price": 18
1102
- },
1103
- {
1104
- "name": "Tata Sampann Turmeric Powder Masala",
1105
- "quantity": 2,
1106
- "price": 85.04
1107
- },
1108
- {
1109
- "name": "Organic Certified Onion (Eerulli)",
1110
- "quantity": 1,
1111
- "price": 66
1112
- },
1113
- {
1114
- "name": "NOTO Strawberry Raspberry Sugar Free Popsicle Ice Cream",
1115
- "quantity": 4,
1116
- "price": 275
1117
- },
1118
- {
1119
- "name": "Premium Guava (Thai)",
1120
- "quantity": 2,
1121
- "price": 154
1122
- },
1123
- {
1124
- "name": "Garlic (Bellulli)",
1125
- "quantity": 1,
1126
- "price": 47
1127
- },
1128
- {
1129
- "name": "Royal Gala Apple (Sebu)",
1130
- "quantity": 1,
1131
- "price": 142
1132
- }
1133
- ],
1134
- "total_price": 841
1135
- }
1136
- ],
1137
- "2025-05-15": [],
1138
- "2025-05-16": [
1139
- {
1140
- "email_number": 1,
1141
- "order_date": "16-May-2025",
1142
- "order_time": "15:43:43",
1143
- "restaurant_name": "Glen's Bakehouse",
1144
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1145
- "items": [
1146
- {
1147
- "name": "Mushroom Puff",
1148
- "quantity": 1,
1149
- "price": 62.86
1150
- },
1151
- {
1152
- "name": "Chicken Puff",
1153
- "quantity": 1,
1154
- "price": 84.23
1155
- }
1156
- ],
1157
- "total_price": 235
1158
- },
1159
- {
1160
- "email_number": 2,
1161
- "order_date": "16-May-2025",
1162
- "order_time": "15:48:57",
1163
- "restaurant_name": "The Himalayan Momo Company",
1164
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1165
- "items": [
1166
- {
1167
- "name": "Woked Maggi",
1168
- "quantity": 1,
1169
- "price": 209
1170
- },
1171
- {
1172
- "name": "Himalayan Steamed Chicken Momos",
1173
- "quantity": 2,
1174
- "price": 318
1175
- }
1176
- ],
1177
- "total_price": 547
1178
- }
1179
- ],
1180
- "2025-05-18": [
1181
- {
1182
- "email_number": 1,
1183
- "order_date": "18-May-2025",
1184
- "order_time": "12:57:21",
1185
- "restaurant_name": "Starbucks Coffee",
1186
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1187
- "items": [
1188
- {
1189
- "name": "Caffe Americano",
1190
- "quantity": 1,
1191
- "price": 315
1192
- }
1193
- ],
1194
- "total_price": 363
1195
- },
1196
- {
1197
- "email_number": 2,
1198
- "order_date": "18-May-2025",
1199
- "order_time": "13:02:51",
1200
- "restaurant_name": "Maiz Mexican Kitchen",
1201
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1202
- "items": [
1203
- {
1204
- "name": "Chips With Guacamole",
1205
- "quantity": 1,
1206
- "price": 249
1207
- },
1208
- {
1209
- "name": "Fresh Tomato Salsa (50ml)",
1210
- "quantity": 1,
1211
- "price": 69
1212
- },
1213
- {
1214
- "name": "Chipotle Chicken Burrito",
1215
- "quantity": 1,
1216
- "price": 299
1217
- }
1218
- ],
1219
- "total_price": 491
1220
- }
1221
- ],
1222
- "2025-05-20": [
1223
- {
1224
- "email_number": 1,
1225
- "order_date": "20-May-2025",
1226
- "order_time": "11:24:05",
1227
- "restaurant_name": "IDC Kitchen",
1228
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1229
- "items": [
1230
- {
1231
- "name": "Vada (1 Pc)",
1232
- "quantity": 1,
1233
- "price": 58
1234
- },
1235
- {
1236
- "name": "Masala Dosa",
1237
- "quantity": 1,
1238
- "price": 140
1239
- }
1240
- ],
1241
- "total_price": 167
1242
- },
1243
- {
1244
- "email_number": 2,
1245
- "order_date": "20-May-2025",
1246
- "order_time": "16:15:50",
1247
- "restaurant_name": "Irani Std. Tea",
1248
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1249
- "items": [
1250
- {
1251
- "name": "Bun Omelette",
1252
- "quantity": 1,
1253
- "price": 139
1254
- },
1255
- {
1256
- "name": "Osmania Biscuits 100 Grams",
1257
- "quantity": 1,
1258
- "price": 100
1259
- },
1260
- {
1261
- "name": "Plain Maggie",
1262
- "quantity": 1,
1263
- "price": 119
1264
- },
1265
- {
1266
- "name": "Bun Maska",
1267
- "quantity": 1,
1268
- "price": 79
1269
- },
1270
- {
1271
- "name": "Irani Ginger Chai",
1272
- "quantity": 1,
1273
- "price": 219
1274
- },
1275
- {
1276
- "name": "Aloo Samosa",
1277
- "quantity": 1,
1278
- "price": 49
1279
- }
1280
- ],
1281
- "total_price": 627
1282
- },
1283
- {
1284
- "email_number": 3,
1285
- "order_date": "20-May-2025",
1286
- "order_time": "20:13:33",
1287
- "restaurant_name": "Gayatri Sandwich(Mithibai College)",
1288
- "delivery_address": "Shobhit, ground floor, Vile Parle East, Vile Parle, Mumbai, Maharashtra, India. (T1)",
1289
- "items": [
1290
- {
1291
- "name": "Sada Sandwich",
1292
- "quantity": 1,
1293
- "price": 50
1294
- },
1295
- {
1296
- "name": "Vada Pav",
1297
- "quantity": 1,
1298
- "price": 25
1299
- }
1300
- ],
1301
- "total_price": 178
1302
- }
1303
- ],
1304
- "2025-05-21": [
1305
- {
1306
- "email_number": 1,
1307
- "order_date": "21-May-2025",
1308
- "order_time": "12:56:56",
1309
- "restaurant_name": "Starbucks Coffee",
1310
- "delivery_address": "Shobhit\n2C, Orchard Green Apartment\n2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1311
- "items": [
1312
- {
1313
- "name": "Cold Brew Black (Cold Brew)",
1314
- "quantity": 1,
1315
- "price": 390
1316
- }
1317
- ],
1318
- "total_price": 401
1319
- },
1320
- {
1321
- "email_number": 2,
1322
- "order_date": "21-May-2025",
1323
- "order_time": "12:58:49",
1324
- "restaurant_name": "Starbucks Coffee",
1325
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1326
- "items": [
1327
- {
1328
- "name": "Caffe Americano",
1329
- "quantity": 1,
1330
- "price": 315
1331
- }
1332
- ],
1333
- "total_price": 363
1334
- },
1335
- {
1336
- "email_number": 3,
1337
- "order_date": "21-May-2025",
1338
- "order_time": "22:07:56",
1339
- "restaurant_name": "Magnolia Bakery",
1340
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1341
- "items": [
1342
- {
1343
- "name": "Chocolate Cake with Chocolate Buttercream Cake Slice",
1344
- "quantity": 1,
1345
- "price": 260
1346
- },
1347
- {
1348
- "name": "CLASSIC TRES LECHES",
1349
- "quantity": 1,
1350
- "price": 410
1351
- }
1352
- ],
1353
- "total_price": 850
1354
- }
1355
- ],
1356
- "2025-05-22": [
1357
- {
1358
- "email_number": 1,
1359
- "order_date": "22-May-2025",
1360
- "order_time": "12:00:34",
1361
- "restaurant_name": "Yogisthaan",
1362
- "delivery_address": "2C, Orchard Green Apartment, 2nd Main Rd, Domlur, Bangalore, Karnataka 560071, India. (Orchard Green)",
1363
- "items": [
1364
- {
1365
- "name": "Poha (quick Of Breakfast)",
1366
- "quantity": 1,
1367
- "price": 288
1368
- },
1369
- {
1370
- "name": "Tapioca (sabu Dana) Khichadi",
1371
- "quantity": 1,
1372
- "price": 252
1373
- }
1374
- ],
1375
- "total_price": 547
1376
- }
1377
- ],
1378
- "2025-05-23": []
1379
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mcp/server/swiggy_scraper.py DELETED
@@ -1,179 +0,0 @@
1
- """
2
- Reusable helper to fetch Swiggy order e-mails and return a list[dict].
3
-
4
- Usage:
5
- from swiggy_scraper import fetch_swiggy_orders
6
- orders = fetch_swiggy_orders("17-May-2025", "20-May-2025")
7
- """
8
-
9
- import os, imaplib, json
10
- from email import message_from_bytes
11
- from bs4 import BeautifulSoup
12
- from openai import OpenAI
13
- from dotenv import load_dotenv
14
- from datetime import datetime, timedelta
15
- from email.utils import parsedate_to_datetime
16
- from zoneinfo import ZoneInfo
17
-
18
- from db_schema import init_db, get_orders_by_date_from_db, save_orders_to_db
19
-
20
-
21
- load_dotenv()
22
-
23
- APP_PASSWORD = os.getenv("APP_PASSWORD")
24
- EMAIL_ID = os.getenv("EMAIL_ID")
25
- OPENAI_KEY = os.getenv("OPENAI_API_KEY")
26
-
27
- client = OpenAI(api_key=OPENAI_KEY)
28
-
29
- def _imap_connect():
30
- m = imaplib.IMAP4_SSL("imap.gmail.com")
31
- m.login(EMAIL_ID, APP_PASSWORD)
32
- m.select('"[Gmail]/All Mail"')
33
- return m
34
-
35
- def _email_to_clean_text(msg):
36
- html = next(
37
- (part.get_payload(decode=True).decode(errors="ignore")
38
- for part in msg.walk()
39
- if part.get_content_type() == "text/html"),
40
- None,
41
- )
42
- if not html:
43
- return ""
44
- soup = BeautifulSoup(html, "html.parser")
45
- for t in soup(["script", "style", "head", "meta", "link"]):
46
- t.decompose()
47
- return "\n".join(
48
- line.strip() for line in soup.get_text("\n").splitlines() if line.strip()
49
- )
50
-
51
- def _get_all_dates(start_date: str, end_date: str):
52
- start = datetime.strptime(start_date, "%d-%b-%Y")
53
- end = datetime.strptime(end_date, "%d-%b-%Y")
54
- delta = (end - start).days + 1
55
- return [(start + timedelta(days=i)).strftime("%Y-%m-%d") for i in range(delta)]
56
-
57
-
58
-
59
-
60
- def _extract_with_llm(email_number, subject, body, email_date, email_time):
61
- current_email = {
62
- "subject": subject,
63
- "body": body
64
- }
65
-
66
- prompt = f"""
67
- You are given a Swiggy order confirmation email with a subject and body.
68
-
69
- Extract and return only the following:
70
- - "restaurant_name": name of the restaurant
71
- - "delivery_address": the delivery address
72
- - "items": a list of ordered items, each with "name", "quantity", and "price" (number)
73
- - "total_price": the total bill paid including taxes, charges, etc.
74
-
75
- Example output format:
76
- {{
77
- "restaurant_name": "Dominos Pizza",
78
- "delivery_address": "123 Main St, City",
79
- "total_price": 567,
80
- "items": [
81
- {{ "name": "Veg Pizza", "quantity": 2, "price": 199 }},
82
- {{ "name": "Coke", "quantity": 1, "price": 45 }}
83
- ]
84
- }}
85
-
86
- Return only valid JSON. No extra text or comments.
87
-
88
- {json.dumps(current_email, indent=2)}
89
- """
90
-
91
-
92
- try:
93
- rsp = client.chat.completions.create(
94
- model="gpt-4o-mini",
95
- temperature=0,
96
- messages=[
97
- {"role": "system", "content": "You are a precise JSON extractor."},
98
- {"role": "user", "content": prompt},
99
- ],
100
- )
101
-
102
- # Attempt to parse the returned content
103
- parsed_data = json.loads(rsp.choices[0].message.content)
104
-
105
- # Wrap into final structure
106
- final_output = {
107
- "email_number": email_number,
108
- "order_date": email_date,
109
- "order_time": email_time,
110
- "restaurant_name": parsed_data.get("restaurant_name", ""),
111
- "delivery_address": parsed_data.get("delivery_address", ""),
112
- "items": parsed_data.get("items", []),
113
- "total_price": parsed_data.get("total_price", 0)
114
- }
115
-
116
-
117
- return final_output
118
-
119
- except json.JSONDecodeError as json_err:
120
- return {
121
- "email_number": email_number,
122
- "error": f"JSON decoding failed: {str(json_err)}",
123
- "raw_response": rsp.choices[0].message.content if 'rsp' in locals() else None
124
- }
125
-
126
- except Exception as e:
127
- return {
128
- "email_number": email_number,
129
- "error": f"Unexpected error: {str(e)}"
130
- }
131
-
132
-
133
-
134
- def fetch_swiggy_orders(start_date: str, end_date: str) -> list[dict]:
135
- mail = _imap_connect()
136
- all_dates = _get_all_dates(start_date, end_date)
137
- orders = []
138
-
139
- for date_str in all_dates:
140
- # 1) Try loading from DB
141
- day_orders = get_orders_by_date_from_db(date_str)
142
- if day_orders:
143
- print(f"{date_str} loaded from DB")
144
- orders.extend(day_orders)
145
- continue
146
-
147
- # 2) Otherwise scrape emails for that date
148
- print(f"Fetching Swiggy emails for {date_str}")
149
- dt_obj = datetime.strptime(date_str, "%Y-%m-%d")
150
- next_day = (dt_obj + timedelta(days=1)).strftime("%d-%b-%Y")
151
- this_day = dt_obj.strftime("%d-%b-%Y")
152
-
153
- crit = f'(FROM "[email protected]") SINCE "{this_day}" BEFORE "{next_day}"'
154
- _, data = mail.search(None, crit)
155
- ids = data[0].split()
156
-
157
- scraped_orders = []
158
- for idx, eid in enumerate(ids, 1):
159
- _, msg_data = mail.fetch(eid, "(RFC822)")
160
- msg = message_from_bytes(msg_data[0][1])
161
- subject = msg.get("Subject", "")
162
- body_text = _email_to_clean_text(msg)
163
-
164
- try:
165
- dt_obj = parsedate_to_datetime(msg["Date"]).astimezone(ZoneInfo("Asia/Kolkata"))
166
- email_date = dt_obj.strftime("%d-%b-%Y")
167
- email_time = dt_obj.strftime("%H:%M:%S")
168
-
169
- order = _extract_with_llm(idx, subject, body_text, email_date, email_time)
170
- scraped_orders.append(order)
171
- except Exception as exc:
172
- scraped_orders.append({"email_number": idx, "error": str(exc)})
173
-
174
- # 3) Save newly scraped data to DB
175
- save_orders_to_db(date_str, scraped_orders)
176
- orders.extend(scraped_orders)
177
-
178
- mail.logout()
179
- return orders
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1 +1,9 @@
1
- huggingface_hub==0.25.2
 
 
 
 
 
 
 
 
 
1
+ huggingface_hub==0.25.2
2
+ uvicorn
3
+ fastapi
4
+ openai
5
+ requests
6
+ python-dateutil
7
+ beautifulsoup4
8
+ python-dotenv
9
+ pydantic[email]
server/email_db.json ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
3
+ "emails": [
4
+ {
5
+ "date": "01-Jan-2025",
6
+ "time": "11:00:26",
7
+ "subject": "2025: A Year to Unite, Innovate, and Lead with Integrity: Let's make\r\n IIT Jodhpur a beacon of excellence and sustainability!",
8
+ "content": "Dear Members of the IIT Jodhpur Fraternity, Students, Staff Members, and Faculty Colleagues, As we stand on the brink of a new year, I take this opportunity to reflect on\u00a0the remarkable journey of IIT Jodhpur so far and the collective efforts that\u00a0have brought us to where we are today over the last\u00a016\u00a0years or so. Each one of you - our faculty,\u00a0students, staff, alumni, and partners, has played a vital role in shaping\u00a0this institute and its evolution as a hub of learning, innovation, and excellence. It is\u00a0your commitment, resilience, and unwavering dedication that inspires all of us to aim higher and envision a future of much greater achievements,\u00a0breaking the\u00a0moulds of conventional thinking and defining excellence at a new\u00a0level. The year 2025 holds immense promise. It is a year when our shared vision of growth, innovation, and sustainability will take centre stage. Our institution stands at the confluence of tradition and modernity, of\u00a0ambition and responsibility. Let this be the year where we align our\u00a0efforts to not only push the boundaries of research and education but\u00a0also embrace a balanced approach toward sustainability in every aspect. Together, we can make IIT Jodhpur a beacon of innovation,\u00a0collaboration, and societal impact.\u00a0Our strength lies in our unity. As a diverse and dynamic community, we\u00a0can bring together varied perspectives, talents, and\u00a0disciplines to create something extraordinary. It is through this synergy that we will achieve the breakthroughs needed to address global\u00a0challenges and contribute meaningfully to the world. Let us continue to\u00a0foster an environment of mutual respect, inclusivity, and shared\u00a0purpose, ensuring that every member of our community feels\u00a0empowered to contribute their best. The journey ahead requires us to focus on strengthening collaborations\u00a0that amplify our impact. By working closely with industry, academia, and\u00a0governmental organizations, we can create pathways to meaningful\u00a0innovation and transformative research. O",
9
+ "message_id": "<CADCv5Wjqd09OCsR0fT2YXv5zzyJT=+xsuvsu4rhLTKbDBznYNw@mail.gmail.com>"
10
+ },
11
+ {
12
+ "date": "14-Jan-2025",
13
+ "time": "09:52:47",
14
+ "subject": "Makar Sankranti, Lohri, Bihu, Pongal: Festivals of Progress and New Aspirations",
15
+ "content": "Dear Members of the IIT Jodhpur Fraternity, \u0906\u092a\u0915\u094b \u0932\u094b\u0939\u093f\u095c\u0940, \u092c\u093f\u0939\u0942, \u092a\u094b\u0902\u0917\u0932 \u0914\u0930 \u092e\u0915\u0930 \u0938\u0902\u0915\u094d\u0930\u093e\u0902\u0924\u093f \u0915\u0940 \u0939\u093e\u0930\u094d\u0926\u093f\u0915 \u0936\u0941\u092d\u0915\u093e\u092e\u0928\u093e\u090f\u0901! \u092d\u093e\u0938\u094d\u0915\u0930\u0938\u094d\u092f \u092f\u0925\u093e \u0924\u0947\u091c\u094b \u092e\u0915\u0930\u0938\u094d\u0925\u0938\u094d\u092f \u0935\u0930\u094d\u0927\u0924\u0947\u0964 \u0924\u0925\u0948\u0935 \u092d\u0935\u0924\u093e\u0902 \u0924\u0947\u091c\u094b \u0935\u0930\u094d\u0927\u0924\u093e\u092e\u093f\u0924\u093f \u0915\u093e\u092e\u092f\u0947\u0964\u0964 \u092d\u0917\u0935\u093e\u0928 \u0938\u0942\u0930\u094d\u092f \u0915\u0947 \u092e\u0915\u0930 \u0930\u093e\u0936\u093f \u092e\u0947\u0902 \u092a\u094d\u0930\u0935\u0947\u0936 \u0924\u0925\u093e \u0909\u0924\u094d\u0924\u0930\u093e\u092f\u0923 \u0939\u094b\u0928\u0947 \u092a\u0930 \u0938\u0902\u092a\u0942\u0930\u094d\u0923 \u092d\u093e\u0930\u0924\u0935\u0930\u094d\u0937 \u092e\u0947\u0902 \u090a\u0930\u094d\u091c\u093e \u0935 \u0909\u0937\u094d\u092e\u093e \u092e\u0947\u0902 \u0935\u0943\u0926\u094d\u0927\u093f \u0915\u0947 \u092a\u094d\u0930\u0924\u0940\u0915-\u092a\u0930\u094d\u0935 \u00a0\"\u092e\u0915\u0930 \u0938\u0902\u0915\u094d\u0930\u093e\u0902\u0924\u093f\" \u092a\u0930 \u0906\u092a\u0915\u093e \u090f\u0935\u0902 \u0906\u092a\u0915\u0947 \u092a\u0930\u093f\u0935\u093e\u0930 \u092e\u0947\u0902 \u0938\u092d\u0940 \u0915\u093e \u091c\u0940\u0935\u0928 \u0905\u0924\u094d\u092f\u0902\u0924 \u092a\u094d\u0930\u0915\u093e\u0936\u092e\u093e\u0928 \u0939\u094b! \u0906\u092a \u0938\u092d\u0940 \u0938\u094d\u0935\u0938\u094d\u0925 \u0930\u0939\u0947\u0902, \u092a\u094d\u0930\u0938\u0928\u094d\u0928 \u0930\u0939\u0947\u0902 \u0914\u0930 \u0938\u0942\u0930\u094d\u092f \u0915\u0940 \u092d\u093e\u0901\u0924\u093f \u0905\u092a\u0928\u0947 \u092a\u094d\u0930\u0915\u093e\u0936 \u0938\u0947 \u0935\u093f\u0936\u094d\u0935 \u0915\u094b \u0906\u0932\u094b\u0915\u093f\u0924 \u0915\u0930\u0947\u0902! \u0906\u0907\u090f, \u0905\u092a\u0928\u0940 \u0906\u0932\u094b\u0915\u0927\u0930\u094d\u092e\u0940 \u0938\u0902\u0938\u094d\u0915\u0943\u0924\u093f \u0915\u0940 \u0935\u093f\u0930\u093e\u0938\u0924 \u0915\u0947 \u0935\u093e\u0939\u0915 \u092c\u0928\u0947\u0902\u0964 \u0909\u0938\u0915\u0947 \u092e\u0939\u0924\u094d\u0924\u094d\u0935 \u090f\u0935\u0902 \u0935\u0948\u091c\u094d\u091e\u093e\u0928\u093f\u0915\u0924\u093e \u0915\u094b \u092a\u0939\u0932\u0947 \u0938\u094d\u0935\u092f\u0902 \u0938\u092e\u091d\u0947\u0902, \u092b\u093f\u0930 \u0905\u092a\u0928\u0940 \u0938\u0902\u0924\u0924\u093f\u092f\u094b\u0902 \u0915\u094b \u092d\u0940 \u0938\u092e\u091d\u093e\u090f\u0901\u0964 \u0939\u092e\u093e\u0930\u0947 \u0924\u094d\u092f\u094b\u0939\u093e\u0930, \u0939\u092e\u093e\u0930\u0940 \u092d\u093e\u0937\u093e, \u0939\u092e\u093e\u0930\u0940 \u092a\u0930\u0902\u092a\u0930\u093e, \u0939\u092e\u093e\u0930\u0940 \u0938\u0902\u0938\u094d\u0915\u0943\u0924\u093f - \u0939\u0940\u0928\u0924\u093e \u0928\u0939\u0940\u0902, \u0917\u0930\u094d\u0935 \u0915\u0940 \u0935\u093f\u0937\u092f\u0935\u0938\u094d\u0924\u0941 \u0939\u0948\u0902\u0964 As we celebrate the auspicious occasion of Makar Sankranti, when the sun begins its northward journey (Uttarayan), let us draw inspiration from this symbol of progress, renewal, and growth. This festival reminds us to embrace change, rise above challenges, and strive for new aspirations. Much like the sun\u2019s steady path, our commitment to advancing knowledge, innovation, and societal impact continues to illuminate the way forward. At IIT Jodhpur, we are driven to explore transformative solutions, foster excellence, and shape a sustainable and inclusive future for ourselves, and the nation. Let us make use of this occasion to reflect on our achievements and renew our dedication to the goals that lie ahead. Together, as a community, we can reach greater heights and leave an enduring legacy for generations to come. May this festive season bring joy, prosperity, and inspiration to you and your families. Let us soar higher, united in our purpose and vision. -- Affectionately Yours..... With warm regards..... Prof. Avinash Kumar Agarwal, FTWAS, FAAAS, FCI, FSAE, FASME, FRSC, FNAE, FNASc, FISEES Director, IIT Jodhpur & Sir J C Bose National Fellow Tel: +91 291 2801011 (Off) Wikipedia: tinyurl.com/bdhe89ew | Scopus: https://tinyurl.com/mwccdcc4 | Google Scholar: https://tinyurl.com/mtbyv7w4 | FUE",
16
+ "message_id": "<CADCv5WgfRV2jFQf2=gfVHw1xfyE87tdqHSVtGQq3S4dhNmwEdA@mail.gmail.com>"
17
+ },
18
+ {
19
+ "date": "25-Jan-2025",
20
+ "time": "19:48:33",
21
+ "subject": "Happy Republic Day-2025",
22
+ "content": "My Dear Students, Faculty and Staff members, \ud83c\uddee\ud83c\uddf3 Greetings on the occasion of the 76th Republic Day! \ud83c\uddee\ud83c\uddf3 As we approach the 26th of January, we unite to celebrate not only the adoption of our Constitution but also the enduring principles of democracy, justice, and equality that define us as individuals and as an institution. This momentous day inspires us to reaffirm our collective commitment to shaping the future of our nation. At IIT Jodhpur, we hold a pivotal role in this journey of progress and innovation. As proud members of this esteemed institution, we bear the responsibility of fostering a culture rooted in innovation, academic excellence, and ethical leadership. Republic Day serves as a powerful reminder of our individual and collective contributions to IIT Jodhpur and the nation\u2014 not only through our collective professional accomplishments but also through the values we instil in our students and the spirit of collaboration and excellence we cultivate among ourselves. On this Republic Day, let us focus on: \u2705 Strengthening research and teaching excellence in our Institute, \u2705 Enhancing our infrastructure, and \u2705 Building a more inclusive and supportive environment for all members of our community. It is through these efforts that we will continue to push the frontiers of knowledge, innovation and excellence, contributing meaningfully to our nation and beyond. I encourage everyone to actively participate in the Republic Day celebrations tomorrow morning and reflect on how we can collectively elevate IIT Jodhpur\u2019s legacy. Together, let us uphold the values of integrity, diversity, and excellence\u2014the core pillars of our nation and our Institute. Wishing you and yours a thoughtful, inspiring, and joyous Republic Day 2025. Jai Hind. Jai Bharat. With warm regards and affection, Prof. Avinash Kumar Agarwal, FTWAS, FAAAS, FCI, FSAE, FASME, FRSC, FNAE, FNASc, FISEES Director, IIT Jodhpur & Sir J C Bose National Fellow Tel: +91 291 2801011 (Off) Wikipedia: tinyurl.com/bd",
23
+ "message_id": "<CADCv5WiULZvioxbVYrmR7mdmZHtB4jQ2P2cG_+S-Sdas1hNyew@mail.gmail.com>"
24
+ },
25
+ {
26
+ "date": "13-Feb-2025",
27
+ "time": "11:37:07",
28
+ "subject": "=?UTF-8?Q?Re=3A_=5Bfaculty=5D_Invitation_to_Hamira_Manganiyar_Group=27?=\r\n\t=?UTF-8?Q?s_Rajasthani_Folk_Music_Performance_Today_=E2=80=93_VIRASAT_2025?=",
29
+ "content": "Dear All, The Institute is organising Virasat 2025, and renowned artists will descend on our campus over the next five days. We must take this opportunity to learn about our cultural heritage and musical\u00a0performances during this period. I will strongly encourage all constituents of our campus community, including students, faculty and staff members and their families, and project staff members, to attend all these programs in the evening over the next five days and enjoy the cultural performances. Best wishes Avinash Kumar Agarwal On Thu, Feb 13, 2025 at 11:26\u202fAM Sherin Sabu < [email protected] > wrote: Dear all, We are delighted to invite you to an enchanting evening of Rajasthani folk music as part of VIRASAT 2025 , organized by IIT Jodhpur in collaboration with SPIC MACAY. \ud83c\udfb6 Performance Details: \ud83d\udccd Venue: Jodhpur Club, IIT Jodhpur \ud83c\udfa4 Artist: Hamira Manganiyar Group (Rajasthani Folk Music) \ud83d\udcc5 Date: Today: 13th February 2025 \u23f0 Time: 7:30 PM Immerse yourself in the vibrant and soulful rhythms of Rajasthan as the Hamira Manganiyar Group brings to life the rich musical traditions of the desert. This performance is a rare opportunity to experience the deep-rooted heritage of folk music passed down through generations. We warmly invite you to join us for this unforgettable musical evening.\u00a0\r\n\r\nPlease bring your family along to share in this cultural celebration! \ud83d\udccc Find attached the official event poster for more details. Looking forward to your presence! Warm Regards, Team Virasat 2025 IIT Jodhpur -- Dr Sherin Sabu Assistant Professor (Sociology), School of Liberal Arts (SoLA) Affiliate Faculty, Center for Emerging Technologies for Sustainable Development (CETSD) IIT Jodhpur",
30
+ "message_id": "<CADCv5WiZNk6BBrYPXhaaN0K_9N-L27ufUfg5JyWTrrJdbnwM=w@mail.gmail.com>"
31
+ },
32
+ {
33
+ "date": "26-Feb-2025",
34
+ "time": "19:54:24",
35
+ "subject": "Greetings on Mahashivratri!",
36
+ "content": "Dear all, Wishing you all a blessed and joyous Mahashivratri! I extend my warmest greetings to all of you and your family members. Mahashivratri is a time of deep spiritual reflection, inner growth, and devotion. This sacred festival symbolizes the triumph of wisdom, devotion, and inner strength, inspiring us to pursue knowledge and morality in all our endeavors. As we celebrate this day with devotion and reflection, let us also reaffirm our commitment to excellence, innovation, and the collective growth of IIT Jodhpur. Together, through dedication and hard work, we should continue to make meaningful contributions to knowledge, technology, and society. With warm regards, Prof. Avinash Kumar Agarwal ..",
37
+ "message_id": "<CADCv5WhSG91tOjiv_+XUUrxvqeOQv4xMocQNsgAC_EuUTQ87jw@mail.gmail.com>"
38
+ },
39
+ {
40
+ "date": "28-Feb-2025",
41
+ "time": "12:05:48",
42
+ "subject": "Re: [faculty] Invitation to celebrate \"National Science Day\" on 28th\r\n February 2025 at IIT Jodhpur",
43
+ "content": "Dear All, Hearty Congratulations to all of you on the occasion of National Science Day 2025. I urge all of you to attend this celebration of National Science Day. Sh Sharad Sarraf, BoG Chairman of IIT Mumbai and Jammu, is the Speaker and the chief guest. He is a strong well-wisher of IIT Jodhpur and we will enrich ourselves by listening to his words, full of wisdom. Best regards Avinash Kumar Agarwal On Wed, Feb 26, 2025 at 6:02\u202fPM Committee for Celebration of Commemorative Days < [email protected] > wrote: Dear All, \u092e\u0939\u093e\u0936\u093f\u0935\u0930\u093e\u0924\u094d\u0930\u093f\u00a0 \u0915\u0940 \u0939\u093e\u0930\u094d\u0926\u093f\u0915 \u0936\u0941\u092d\u0915\u093e\u092e\u0928\u093e\u090f\u0902 / Happy MahaShivratri....! \u0938\u094d\u092e\u093e\u0930\u0915 \u0926\u093f\u0935\u0938 \u0938\u092e\u093e\u0930\u094b\u0939 \u0938\u092e\u093f\u0924\u093f (\u0938\u0940\u0938\u0940\u0938\u0940\u0921\u0940) \u0915\u0940 \u0913\u0930 \u0938\u0947, \u092d\u093e\u0930\u0924\u0940\u092f \u092a\u094d\u0930\u094c\u0926\u094d\u092f\u094b\u0917\u093f\u0915\u0940 \u0938\u0902\u0938\u094d\u0925\u093e\u0928 \u091c\u094b\u0927\u092a\u0941\u0930 \u092e\u0947\u0902 28 \u092b\u0930\u0935\u0930\u0940, 2025 (\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930) \u0915\u094b \u0930\u093e\u0937\u094d\u091f\u094d\u0930\u0940\u092f \u0935\u093f\u091c\u094d\u091e\u093e\u0928 \u0926\u093f\u0935\u0938\u00a0 2025 \u0915\u0947 \u0905\u0935\u0938\u0930 \u092a\u0930 \u0939\u092e \u0906\u092a\u0915\u094b \u00a0\u0939\u093e\u0930\u094d\u0926\u093f\u0915 \u0928\u093f\u092e\u0902\u0924\u094d\u0930\u0923 \u0926\u0947\u0924\u0947\u00a0 \u0939\u0948\u0902 \u0964 \u0939\u092e\u00a0\u00a0\u0907\u0938 \u092e\u0939\u0924\u094d\u0935\u092a\u0942\u0930\u094d\u0923 \u0915\u093e\u0930\u094d\u092f\u0915\u094d\u0930\u092e \u092e\u0947\u0902 \u0906\u092a\u0915\u0947 \u0936\u093e\u092e\u093f\u0932 \u0939\u094b\u0928\u0947 \u0915\u0947 \u0938\u092e\u094d\u092e\u093e\u0928 \u0915\u0940 \u0909\u0924\u094d\u0938\u0941\u0915\u0924\u093e \u0938\u0947 \u092a\u094d\u0930\u0924\u0940\u0915\u094d\u0937\u093e \u0915\u0930\u0947\u0902\u0917\u0947\u0964 On behalf of the Committee for Celebration of Commemorative Days (CCCD) at IIT Jodhpur, we cordially invite you to join us in commemorating the National Science Day 2025 on February 28, 2025 (Friday) . We eagerly anticipate the honour of having you at this momentous event. Program: National Science Day 2025 Date: 28th February 2025 (Friday) Venue: Jodhpur Club Time: 5:45 PM onwards Program details: Time Event 05:45 \u2013 06:05 PM Scientific Demonstration & Tea -Refreshments 06:05 \u2013 06:10 PM Lamp Lighting & felicitation 06:10 \u2013 06:20 PM Welcome address by the Director 06:20 \u2013 06:45 PM Talk and interaction by the Chief Guest 06:45 \u2013 06:50 PM Felicitation of Guests 06:50 \u2013 07:00 PM Library App Release 07:00 \u2013 07:05 PM Quiz Session 07:05 \u2013 07:15 PM Felicitation to ACAC students 07:15 \u2013 07:20 PM Vote of Thanks 07:20 PM National Anthem Your presence and active participation will contribute significantly to the success of this celebration. With warm regards, Himmat Singh Assistant Registrar ___________________________________________________ \u0938\u094d\u092e\u093e\u0930\u0915 \u0926\u093f\u0935\u0938 \u0938\u092e\u093e\u0930\u094b\u0939 \u0938\u092e\u093f\u0924\u093f / Committee for Celebration of Commemorative Days (CCCD) \u0906\u0908\u0906\u0908",
44
+ "message_id": "<CADCv5WjLQTBkWxUB7XuOmQEKmNJftW5Orw8rnnjX-cAQ4bPFuw@mail.gmail.com>"
45
+ },
46
+ {
47
+ "date": "01-Apr-2025",
48
+ "time": "10:53:52",
49
+ "subject": "Fwd: FY Closure and Updates",
50
+ "content": "Dear Students, Today, April 1, marks an important day because we are taking two important steps in the direction of our evolution as a mature institute of higher learning. 1. Today, our Health Center starts working in autonomous mode, managed and operated by OUR OWN team. 2. Today, our transport services also start operating in autonomous mode, managed and operated by OUR OWN team. These two are definitely two big steps in the evolution of our institute. I would also like to put on record my deep appreciation of the teams of the Health Center, led by Prof. Anil Tiwari and Dr Neha Sharma, and the transport team, led by Prof. Shree Prakash Tiwari and Sandeep Chandel. Please join me in congratulating them for a good start. While these are big transitions, it is\u00a0possible that there might be some perturbations in services in the initial period. Please give your feedback to the process owners, and actions will be taken to minimise the inconveniences and meet all genuine expectations. Best regards -- With warm regards..... Prof. Avinash Kumar Agarwal, FTWAS, FAAAS, FCI, FSAE, FASME, FRSC, FNAE, FNASc, FISEES Director, IIT Jodhpur & Sir J C Bose National Fellow Tel: +91 291 2801011 (Off) Wikipedia: tinyurl.com/bdhe89ew | Scopus: https://tinyurl.com/mwccdcc4 | Google Scholar: https://tinyurl.com/mtbyv7w4 | FUEL: https://tinyurl.com/bdzn4r28 | Orcid: https://tinyurl.com/537m3tad ------------------------------ ------------------------------ ---------------- \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of The World Academy of Science \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Combustion Institute, USA \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of American Association for the Advancement of Science \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of American Society of Mechanical Engineers \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Society of Automotive Engineers International, USA \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of World Society for Sustainable Energy Technologies, UK \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Royal Society of Chemistry, UK \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of National Academy of Sciences India \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Indian National Academy of Engineering \u2022\u00a0 \u00a0 \u00a0 \u00a0F",
51
+ "message_id": "<CADCv5WhGgVj0LCjvkTKda_mNxQ6WqQdGmP1afV=sj2v=WSBwow@mail.gmail.com>"
52
+ },
53
+ {
54
+ "date": "23-Apr-2025",
55
+ "time": "20:27:50",
56
+ "subject": "Directorate Shifted to Chankya Complex",
57
+ "content": "Dear All, This is to inform you that all the offices of the Deans, Registrar, DD and D have moved back to Chanamkya\u00a0Complex. -- With warm regards..... Prof. Avinash Kumar Agarwal, FTWAS, FAAAS, FCI, FSAE, FASME, FRSC, FNAE, FNASc, FISEES Director, IIT Jodhpur & Sir J C Bose National Fellow Tel: +91 291 2801011 (Off) Wikipedia: tinyurl.com/bdhe89ew | Scopus: https://tinyurl.com/mwccdcc4 | Google Scholar: https://tinyurl.com/mtbyv7w4 | FUEL: https://tinyurl.com/bdzn4r28 | Orcid: https://tinyurl.com/537m3tad ------------------------------ ------------------------------ ---------------- \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of The World Academy of Science \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Combustion Institute, USA \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of American Association for the Advancement of Science \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of American Society of Mechanical Engineers \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Society of Automotive Engineers International, USA \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of World Society for Sustainable Energy Technologies, UK \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Royal Society of Chemistry, UK \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of National Academy of Sciences India \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Indian National Academy of Engineering \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of International Society of Energy, Environment, and Sustainability ------------------------------ ------------------------------ ------------- \u2022\u00a0 \u00a0 \u00a0 \u00a0Shanti Swarup Bhatnagar Award-2016 \u2022\u00a0 \u00a0 \u00a0 \u00a0Editor of FUEL \u2022\u00a0 \u00a0 \u00a0 \u00a0Associate Editor of ASME Open Journal of Engineering \u2022\u00a0 \u00a0 \u00a0 \u00a0Associate Editor of SAE International Journal of Engines ------------------------------ ------------------------------ --------------",
58
+ "message_id": "<CADCv5WhB=aoNjykLwPj9wY-ZNTCxnBp5EFsPriDs+mpH9Fi-WA@mail.gmail.com>"
59
+ },
60
+ {
61
+ "date": "01-May-2025",
62
+ "time": "12:20:20",
63
+ "subject": "Thank You",
64
+ "content": "Dear\r\nColleagues I want to thank all the stakeholders for their kind cooperation,\r\nenabling me to complete one year as Director of IIT Jodhpur. I joined the\r\nInstitute on 1 st May 2024. I realised this Institute has great potential and can break into the top echelons of\r\nranking among engineering institutions in the country and the world. However,\r\nto achieve this, all of us must work as a unified team. From my\r\nside, I assure you that I will make all possible efforts to ensure that fair\r\nand transparent governance processes are in place and we, as a team, make all\r\nthe efforts in the right direction. In the last\r\nyear, extra-mural research grants to IIT jodhpur have doubled, and project endorsements\r\nand publications have significantly increased; however, there are miles to go. I hope we\r\nall continue to work relentlessly to pursue excellence in our activities, be\r\nloyal to the Institute, and do all our duties with dedication, sincerity and\r\nhonesty. This Institute cannot have any room for corruption, nepotism and\r\nregionalism. As IIT Jodhpur stakeholders, we must commit to having excellent\r\nconduct and setting an example for others to follow. Wishing you\r\nall the very best Affectionately\r\nyours Avinash Kumar Agarwal, FTWAS, FAAAS, FCI, FSAE, FASME, FRSC, FNAE, FNASc, FISEES Director, IIT Jodhpur & Sir J C Bose National Fellow Tel: +91 291 2801011 (Off) Wikipedia: tinyurl.com/bdhe89ew | Scopus: https://tinyurl.com/mwccdcc4 | Google Scholar: https://tinyurl.com/mtbyv7w4 | FUEL: https://tinyurl.com/bdzn4r28 | Orcid: https://tinyurl.com/537m3tad ------------------------------ ------------------------------ ---------------- \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of The World Academy of Science \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Combustion Institute, USA \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of American Association for the Advancement of Science \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of American Society of Mechanical Engineers \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Society of Automotive Engineers International, USA \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of World Society for Sustainable Energy Technol",
65
+ "message_id": "<CADCv5Wjxn7Pj2XXBf4n2S0PyJQapU1aOOvfHfjjtr4xfSWbeKw@mail.gmail.com>"
66
+ },
67
+ {
68
+ "date": "07-May-2025",
69
+ "time": "20:56:02",
70
+ "subject": "Instruction for Next few days: Urgent attention",
71
+ "content": "Dear Faculty Members, Staff Members, Students and Other Constituents of our campus community You are aware that we are passing through a tough time, as far as national security is concerned. Today, we have done a drill for the evacuation of the campus community in the event of an air strike by our nemesis. We will have less than 5 minutes for blackout and evacuation into the tunnels. The next few days and nights are very critical, and we may be one of the soft targets. Hence, adequate care and precaution are important to all of us. Please note: 1. There will be no more drills. In case you hear a siren (Oscillating), it means an impending attack, and we will have less than 5 minutes to get into the tunnel hideouts.\u00a0The flat siren will mean that the danger has passed, and now it is safe to venture out. Enemy fighters\u00a0and missiles will reach us in 5-10 minutes after crossing the border, and that's all we would have to ensure our safety. 2. Today evening, we will do black out\u00a0drill between 10-10.15 PM. There will be no siren; hence, all of you are to follow the procedure voluntarily on your own. The power will be cut (If it is resumed by JVVNL). Every possible light source must be turned off. The lights can be put on again after 15 minutes, at 10.15 PM tonight. 3. In the event of an impending attack, the lights will be cut off centrally after the siren goes off, in the next 2-3 minutes.\u00a0That's all the time, you will have to come down the roads and move into the tunnels. It is\u00a0advised to carry your own water bottle in such an event. 4. There should be no live streaming, photographs posted on social media for these or sharing of this email on any platform. This will put all of us in danger. On each tunnel entry point, we will post security guards to\u00a0guide\u00a0you safely. Please ensure that you do not panic and move in a\u00a0disciplined manner into the tunnels,\u00a0when and if required. If you have already posted the photos and videos of tunnels on your social media accounts, please d",
72
+ "message_id": "<CADCv5WiK10w-aj0Vn2vq+bT1qViromAsfpwd+DPWGeYx2zspXA@mail.gmail.com>"
73
+ },
74
+ {
75
+ "date": "07-May-2025",
76
+ "time": "22:28:02",
77
+ "subject": "Re: Instruction for Next few days: Urgent attention",
78
+ "content": "Dear All, Thanks. Black out drill was an outstanding success and we figured out some lapses, which have been fixed. Be alert and all of us know the steps, in case required, to keep us safe. Be calm and hope that our forces will keep our nemesis at bay and we are not required to be in the hideout. In any case, now we all know the next steps and hopefully we will sleep peacefully. Best regards Avinash Kumar Agarwal On Wed, 7 May, 2025, 20:56 Director, IIT Jodhpur, < [email protected] > wrote: Dear Faculty Members, Staff Members, Students and Other Constituents of our campus community You are aware that we are passing through a tough time, as far as national security is concerned. Today, we have done a drill for the evacuation of the campus community in the event of an air strike by our nemesis. We will have less than 5 minutes for blackout and evacuation into the tunnels. The next few days and nights are very critical, and we may be one of the soft targets. Hence, adequate care and precaution are important to all of us. Please note: 1. There will be no more drills. In case you hear a siren (Oscillating), it means an impending attack, and we will have less than 5 minutes to get into the tunnel hideouts.\u00a0The flat siren will mean that the danger has passed, and now it is safe to venture out. Enemy fighters\u00a0and missiles will reach us in 5-10 minutes after crossing the border, and that's all we would have to ensure our safety. 2. Today evening, we will do black out\u00a0drill between 10-10.15 PM. There will be no siren; hence, all of you are to follow the procedure voluntarily on your own. The power will be cut (If it is resumed by JVVNL). Every possible light source must be turned off. The lights can be put on again after 15 minutes, at 10.15 PM tonight. 3. In the event of an impending attack, the lights will be cut off centrally after the siren goes off, in the next 2-3 minutes.\u00a0That's all the time, you will have to come down the roads and move into the tunnels. It is\u00a0advis",
79
+ "message_id": "<CADCv5Wh8x5L+Z=5bNYG_f=tbX=Lo0HH=1cT3yTw9Huv4Kr+iWQ@mail.gmail.com>"
80
+ },
81
+ {
82
+ "date": "08-May-2025",
83
+ "time": "11:06:17",
84
+ "subject": "Re: [faculty] Re: Instruction for Next few days: Urgent attention",
85
+ "content": "Dear All, There was a complete blackout in the entire city last night from 12-4 AM as all feeders were shut down by the district administration, and there was no power supply anywhere in the city. This might have led to some inconveniences\u00a0for all of us in these difficult times. These directions of complete blackout\u00a0are likely to be given again by the district administration over the next few days, depending on threat perception and intel inputs. I am trying to get our electricity supplies uninterrupted by discussing with the district admin so that the campus community stays indoors during these long and declared blackout periods. It is likely that we will keep all our street lights and public lights off starting the evenings over the next few days. The campus community is advised to ensure that they have all lights off during the declared blackout periods,\u00a0without any defaults. Any defaults may lead to our staying without electricity,\u00a0at par with the rest of the city. In addition, in the event of a siren going off, everyone needs to rush to the hideouts, as per our previous drill. Siren will indicate an upcoming aerial raid. I would also like to reiterate that there is no specific additional threat to the IITJ community. The threat to us is similar to that of any other part of the country, and there is no specific need for any panic or concern. We are all in this situation, as a united Bharat, and we must all face it bravely. There is no need for any anxiety or nervousness by seeing our emails about the safety protocols. These are just to ensure that in the event of any adverse action by our nemesis, our campus community stays safe, and all these measures taken by IITJ and drills were part of precautionary measures taken on the directions of the district administration. You may please contact Prof. Bhabani Satapathi, Prof. S R Vadera or Col Virendra Singh Rathore in case of any genuine concerns. Best wishes Avinash Kumar Agarwal On Wed, May 7, 2025 at 11:32\u202fPM Avin",
86
+ "message_id": "<CADCv5WixMeCadxAfjoOoNrBR2WotkVyw-678FsLfEODX5KRisA@mail.gmail.com>"
87
+ },
88
+ {
89
+ "date": "08-May-2025",
90
+ "time": "21:42:20",
91
+ "subject": "Re: Important Notice: Citywide Blackout and Campus Power Supply Instructions",
92
+ "content": "Evacuation to tunnels immediately On Thu, 8 May, 2025, 21:32 Deputy Director IIT Jodhpur, < [email protected] > wrote: Dear All, As per instructions from the District Administration, there will be a blackout and no power supply tonight across the entire city of Jodhpur. However, following discussions between our Director and the city administration, a special provision has been made to allow limited power supply within our campus\u2014only to Type C, Type B, and Hostel areas\u2014provided that the campus community strictly adheres to the following: \u2022\tRemain indoors throughout the blackout period. \u2022\tKeep all lights switched off; only fans may be used. \u2022\tNo lights should be visible from outside under any circumstance. Please note, no power supply will be provided to any other areas of the campus apart from the three mentioned above. Your cooperation is essential in ensuring compliance with this directive and maintaining safety for all. Warm regards, Prof. Bhabani Kumar Satapathy",
93
+ "message_id": "<CADCv5WiFEi5Qbim6PqHk7E-fu=qv4XP5ZDbg3uQgBAHou3Tzmw@mail.gmail.com>"
94
+ },
95
+ {
96
+ "date": "10-May-2025",
97
+ "time": "18:33:45",
98
+ "subject": "Updates",
99
+ "content": "Dear All, We should be aware that the threat is now over, and we can resume our \"Business as usual\". Those who are planning to go should not, and those who have already left the campus can make their plans to return, as per their convenience. Congratulations to all for showing an absolute resolve to tackle this national threat and showing that we are Bharat of the 21st century, a \"Naya Bharat\". This also calls for all IITJ constituents to work actively towards the national defence and offence capabilities. Jai Hind and Jai Bharat. Best regards Avinash Kumar AGarwal",
100
+ "message_id": "<CADCv5Wg8YogC8kG2DH7w=GmpZiKb80_nXMhBFRJjNTUZBVGQVQ@mail.gmail.com>"
101
+ },
102
+ {
103
+ "date": "24-May-2025",
104
+ "time": "21:46:02",
105
+ "subject": "Great News",
106
+ "content": "Dear All, I am delighted to share with you some fantastic news. Our Jaipur campus has come one step closer to realisation with the Government of Rajasthan agreeing \"in principle\" to allocate us land and buildings. Now we have secured a letter of intent from the GoR, which now needs to be taken up with the Ministry of Education and the Ministry of Finance, Government of India. Once these approvals are secured, we will realise our dream of having a Jaipur campus, apart from our main campus in Jodhpur. We are also beginning to work on our small footprint\u00a0campus in Jaisalmer to\u00a0complete our dream of IITJ3. This is a big feat for us as an institute to get the GoR to agree to our proposal. Hopefully, more good things will follow. -- With warm regards..... Prof. Avinash Kumar Agarwal, FTWAS, FAAAS, FCI, FSAE, FASME, FRSC, FNAE, FNASc, FISEES Director, IIT Jodhpur & Sir J C Bose National Fellow Tel: +91 291 2801011 (Off) Wikipedia: tinyurl.com/bdhe89ew | Scopus: https://tinyurl.com/mwccdcc4 | Google Scholar: https://tinyurl.com/mtbyv7w4 | FUEL: https://tinyurl.com/bdzn4r28 | Orcid: https://tinyurl.com/537m3tad ------------------------------ ------------------------------ ---------------- \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of The World Academy of Science \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Combustion Institute, USA \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of American Association for the Advancement of Science \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of American Society of Mechanical Engineers \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Society of Automotive Engineers International, USA \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of World Society for Sustainable Energy Technologies, UK \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Royal Society of Chemistry, UK \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of National Academy of Sciences India \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of Indian National Academy of Engineering \u2022\u00a0 \u00a0 \u00a0 \u00a0Fellow of International Society of Energy, Environment, and Sustainability ------------------------------ ------------------------------ ------------- \u2022\u00a0 \u00a0 \u00a0 \u00a0Shanti Swarup Bhatnagar Award-2016 \u2022\u00a0 \u00a0 \u00a0 \u00a0Editor of FUEL \u2022\u00a0 \u00a0 \u00a0 \u00a0Associate Editor of ASME Open Journal of Enginee",
107
+ "message_id": "<CADCv5Wik-=UY6XFVqbtHBPNYXGe3gWkYE82qV286AySDp1qL_w@mail.gmail.com>"
108
+ },
109
+ {
110
+ "date": "07-Jun-2025",
111
+ "time": "12:44:03",
112
+ "subject": "Greetings on the occasion of Eid al-Adha!",
113
+ "content": "Dear All, On the joyous occasion of Eid al-Adha, I extend my warmest greetings to all members of IITJ. This festival, rooted in the values of personal sacrifices, compassion, empathy and unity, inspires us to strengthen our bonds and work together for the greater good. At IIT Jodhpur, we are committed to nurturing an environment of compassion, empathy, honesty, collaboration, innovation, and integrity. As we celebrate this auspicious day, let us reaffirm our dedication to positive growth, unite in our pursuit of excellence, and resolve to uphold transparency. May this festival bring peace, prosperity, and harmony to our vibrant campus community and its constituents. Best wishes, Affectionately Yours Avinash Kumar Agarwal Director",
114
+ "message_id": "<CADCv5Wj4J-FCNitA2r_m9uT5pFZNz-OQFXTwQM1em+ki69=9jQ@mail.gmail.com>"
115
+ }
116
+ ],
117
+ "last_scraped": "07-Jun-2025"
118
+ }
119
+ }
server/email_scraper.py ADDED
@@ -0,0 +1,267 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Enhanced Email Scraper with Intelligent Caching
4
+ """
5
+
6
+ import os
7
+ import imaplib
8
+ import json
9
+ from email import message_from_bytes
10
+ from bs4 import BeautifulSoup
11
+ from datetime import datetime, timedelta
12
+ from dotenv import load_dotenv
13
+ from zoneinfo import ZoneInfo
14
+ from email.utils import parsedate_to_datetime
15
+ from typing import List, Dict
16
+
17
+ load_dotenv()
18
+
19
+ # Email credentials
20
+ APP_PASSWORD = os.getenv("APP_PASSWORD")
21
+ EMAIL_ID = os.getenv("EMAIL_ID")
22
+ EMAIL_DB_FILE = "email_db.json"
23
+
24
+ def _imap_connect():
25
+ """Connect to Gmail IMAP server"""
26
+ try:
27
+ mail = imaplib.IMAP4_SSL("imap.gmail.com")
28
+ mail.login(EMAIL_ID, APP_PASSWORD)
29
+ mail.select('"[Gmail]/All Mail"')
30
+ return mail
31
+ except Exception as e:
32
+ print(f"IMAP connection failed: {e}")
33
+ raise
34
+
35
+ def _email_to_clean_text(msg):
36
+ """Extract clean text from email message"""
37
+ # Try HTML first
38
+ html_content = None
39
+ text_content = None
40
+
41
+ if msg.is_multipart():
42
+ for part in msg.walk():
43
+ content_type = part.get_content_type()
44
+ if content_type == "text/html":
45
+ try:
46
+ html_content = part.get_payload(decode=True).decode(errors="ignore")
47
+ except:
48
+ continue
49
+ elif content_type == "text/plain":
50
+ try:
51
+ text_content = part.get_payload(decode=True).decode(errors="ignore")
52
+ except:
53
+ continue
54
+ else:
55
+ # Non-multipart message
56
+ content_type = msg.get_content_type()
57
+ try:
58
+ content = msg.get_payload(decode=True).decode(errors="ignore")
59
+ if content_type == "text/html":
60
+ html_content = content
61
+ else:
62
+ text_content = content
63
+ except:
64
+ pass
65
+
66
+ # Clean HTML content
67
+ if html_content:
68
+ soup = BeautifulSoup(html_content, "html.parser")
69
+ # Remove script and style elements
70
+ for script in soup(["script", "style"]):
71
+ script.decompose()
72
+ return soup.get_text(separator=' ', strip=True)
73
+ elif text_content:
74
+ return text_content.strip()
75
+ else:
76
+ return ""
77
+
78
+ def _load_email_db() -> Dict:
79
+ """Load email database from file"""
80
+ if not os.path.exists(EMAIL_DB_FILE):
81
+ return {}
82
+ try:
83
+ with open(EMAIL_DB_FILE, "r") as f:
84
+ return json.load(f)
85
+ except (json.JSONDecodeError, IOError):
86
+ print(f"Warning: Could not load {EMAIL_DB_FILE}, starting with empty database")
87
+ return {}
88
+
89
+ def _save_email_db(db: Dict):
90
+ """Save email database to file"""
91
+ try:
92
+ with open(EMAIL_DB_FILE, "w") as f:
93
+ json.dump(db, f, indent=2)
94
+ except IOError as e:
95
+ print(f"Error saving database: {e}")
96
+ raise
97
+
98
+ def _date_to_imap_format(date_str: str) -> str:
99
+ """Convert DD-MMM-YYYY to IMAP date format"""
100
+ try:
101
+ dt = datetime.strptime(date_str, "%d-%b-%Y")
102
+ return dt.strftime("%d-%b-%Y")
103
+ except ValueError:
104
+ raise ValueError(f"Invalid date format: {date_str}. Expected DD-MMM-YYYY")
105
+
106
+ def _is_date_in_range(email_date: str, start_date: str, end_date: str) -> bool:
107
+ """Check if email date is within the specified range"""
108
+ try:
109
+ email_dt = datetime.strptime(email_date, "%d-%b-%Y")
110
+ start_dt = datetime.strptime(start_date, "%d-%b-%Y")
111
+ end_dt = datetime.strptime(end_date, "%d-%b-%Y")
112
+ return start_dt <= email_dt <= end_dt
113
+ except ValueError:
114
+ return False
115
+
116
+ def scrape_emails_from_sender(sender_email: str, start_date: str, end_date: str) -> List[Dict]:
117
+ """
118
+ Scrape emails from specific sender within date range
119
+ Uses intelligent caching to avoid re-scraping
120
+ """
121
+ print(f"Scraping emails from {sender_email} between {start_date} and {end_date}")
122
+
123
+ # Load existing database
124
+ db = _load_email_db()
125
+ sender_email = sender_email.lower().strip()
126
+
127
+ # Check if we have cached emails for this sender
128
+ if sender_email in db:
129
+ cached_emails = db[sender_email].get("emails", [])
130
+
131
+ # Filter cached emails by date range
132
+ filtered_emails = [
133
+ email for email in cached_emails
134
+ if _is_date_in_range(email["date"], start_date, end_date)
135
+ ]
136
+
137
+ # Check if we need to scrape more recent emails
138
+ last_scraped = db[sender_email].get("last_scraped", "01-Jan-2020")
139
+ today = datetime.today().strftime("%d-%b-%Y")
140
+
141
+ if last_scraped == today and filtered_emails:
142
+ print(f"Using cached emails (last scraped: {last_scraped})")
143
+ return filtered_emails
144
+
145
+ # Need to scrape emails
146
+ try:
147
+ mail = _imap_connect()
148
+
149
+ # Prepare IMAP search criteria
150
+ start_imap = _date_to_imap_format(start_date)
151
+ # Add one day to end_date for BEFORE criteria (IMAP BEFORE is exclusive)
152
+ end_dt = datetime.strptime(end_date, "%d-%b-%Y") + timedelta(days=1)
153
+ end_imap = end_dt.strftime("%d-%b-%Y")
154
+
155
+ search_criteria = f'(FROM "{sender_email}") SINCE "{start_imap}" BEFORE "{end_imap}"'
156
+ print(f"IMAP search: {search_criteria}")
157
+
158
+ # Search for emails
159
+ status, data = mail.search(None, search_criteria)
160
+ if status != 'OK':
161
+ raise Exception(f"IMAP search failed: {status}")
162
+
163
+ email_ids = data[0].split()
164
+ print(f"Found {len(email_ids)} emails")
165
+
166
+ scraped_emails = []
167
+
168
+ # Process each email
169
+ for i, email_id in enumerate(email_ids):
170
+ try:
171
+ print(f"Processing email {i+1}/{len(email_ids)}")
172
+
173
+ # Fetch email
174
+ status, msg_data = mail.fetch(email_id, "(RFC822)")
175
+ if status != 'OK':
176
+ continue
177
+
178
+ # Parse email
179
+ msg = message_from_bytes(msg_data[0][1])
180
+
181
+ # Extract information
182
+ subject = msg.get("Subject", "No Subject")
183
+ content = _email_to_clean_text(msg)
184
+
185
+ # Parse date
186
+ date_header = msg.get("Date", "")
187
+ if date_header:
188
+ try:
189
+ dt_obj = parsedate_to_datetime(date_header)
190
+ # Convert to IST
191
+ ist_dt = dt_obj.astimezone(ZoneInfo("Asia/Kolkata"))
192
+ email_date = ist_dt.strftime("%d-%b-%Y")
193
+ email_time = ist_dt.strftime("%H:%M:%S")
194
+ except:
195
+ email_date = datetime.today().strftime("%d-%b-%Y")
196
+ email_time = "00:00:00"
197
+ else:
198
+ email_date = datetime.today().strftime("%d-%b-%Y")
199
+ email_time = "00:00:00"
200
+
201
+ # Get message ID for deduplication
202
+ message_id = msg.get("Message-ID", f"missing-{email_id.decode()}")
203
+
204
+ scraped_emails.append({
205
+ "date": email_date,
206
+ "time": email_time,
207
+ "subject": subject,
208
+ "content": content[:2000], # Limit content length
209
+ "message_id": message_id
210
+ })
211
+
212
+ except Exception as e:
213
+ print(f"Error processing email {email_id}: {e}")
214
+ continue
215
+
216
+ mail.logout()
217
+
218
+ # Update database
219
+ if sender_email not in db:
220
+ db[sender_email] = {"emails": [], "last_scraped": ""}
221
+
222
+ # Merge with existing emails (avoid duplicates)
223
+ existing_emails = db[sender_email].get("emails", [])
224
+ existing_ids = {email.get("message_id") for email in existing_emails}
225
+
226
+ new_emails = [
227
+ email for email in scraped_emails
228
+ if email["message_id"] not in existing_ids
229
+ ]
230
+
231
+ # Update database
232
+ db[sender_email]["emails"] = existing_emails + new_emails
233
+ db[sender_email]["last_scraped"] = datetime.today().strftime("%d-%b-%Y")
234
+
235
+ # Save database
236
+ _save_email_db(db)
237
+
238
+ # Return filtered results
239
+ all_emails = db[sender_email]["emails"]
240
+ filtered_emails = [
241
+ email for email in all_emails
242
+ if _is_date_in_range(email["date"], start_date, end_date)
243
+ ]
244
+
245
+ print(f"Scraped {len(new_emails)} new emails, returning {len(filtered_emails)} in date range")
246
+ return filtered_emails
247
+
248
+ except Exception as e:
249
+ print(f"Email scraping failed: {e}")
250
+ raise
251
+
252
+ # Test the scraper
253
+ if __name__ == "__main__":
254
+ # Test scraping
255
+ try:
256
+ emails = scrape_emails_from_sender(
257
258
+ "01-Jun-2025",
259
+ "07-Jun-2025"
260
+ )
261
+
262
+ print(f"\nFound {len(emails)} emails:")
263
+ for email in emails[:3]: # Show first 3
264
+ print(f"- {email['date']} {email['time']}: {email['subject']}")
265
+
266
+ except Exception as e:
267
+ print(f"Test failed: {e}")
server/main.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from routes import router
4
+
5
+ app = FastAPI(
6
+ title="Email Query System",
7
+ description="Natural language email querying with intent classification",
8
+ version="1.0.0"
9
+ )
10
+
11
+ # Add CORS middleware
12
+ app.add_middleware(
13
+ CORSMiddleware,
14
+ allow_origins=["*"],
15
+ allow_credentials=True,
16
+ allow_methods=["*"],
17
+ allow_headers=["*"],
18
+ )
19
+
20
+ # Include routes
21
+ app.include_router(router, prefix="/api/v1")
22
+
23
+ @app.get("/")
24
+ def root():
25
+ return {
26
+ "message": "Email Query System API",
27
+ "docs": "/docs",
28
+ "health": "/api/v1/health"
29
+ }
server/query_parser.py ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Query Parser with Intent Classification and Name-to-Email Resolution
4
+ """
5
+
6
+ import json
7
+ import os
8
+ from datetime import datetime, timedelta
9
+ from openai import OpenAI
10
+ from typing import Dict, Optional, Tuple
11
+ from dotenv import load_dotenv # <-- Add this
12
+
13
+ # Load environment variables from .env file
14
+ load_dotenv() # <-- Add this
15
+
16
+ # Initialize OpenAI client
17
+ client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
18
+ # File paths
19
+ NAME_MAPPING_FILE = "name_mapping.json"
20
+ EMAIL_DB_FILE = "email_db.json"
21
+
22
+ def _llm(messages, model="gpt-4o-mini", temperature=0):
23
+ """Helper function to call OpenAI API"""
24
+ rsp = client.chat.completions.create(
25
+ model=model,
26
+ temperature=temperature,
27
+ messages=messages,
28
+ )
29
+ return rsp.choices[0].message.content.strip()
30
+
31
+ def _load_name_mapping() -> Dict[str, str]:
32
+ """Load name to email mapping from JSON file"""
33
+ if not os.path.exists(NAME_MAPPING_FILE):
34
+ return {}
35
+ try:
36
+ with open(NAME_MAPPING_FILE, "r") as f:
37
+ return json.load(f)
38
+ except (json.JSONDecodeError, IOError):
39
+ return {}
40
+
41
+ def _save_name_mapping(mapping: Dict[str, str]):
42
+ """Save name to email mapping to JSON file"""
43
+ with open(NAME_MAPPING_FILE, "w") as f:
44
+ json.dump(mapping, f, indent=2)
45
+
46
+ def _load_email_db() -> Dict:
47
+ """Load email database"""
48
+ if not os.path.exists(EMAIL_DB_FILE):
49
+ return {}
50
+ try:
51
+ with open(EMAIL_DB_FILE, "r") as f:
52
+ return json.load(f)
53
+ except (json.JSONDecodeError, IOError):
54
+ return {}
55
+
56
+ def _save_email_db(db: Dict):
57
+ """Save email database"""
58
+ with open(EMAIL_DB_FILE, "w") as f:
59
+ json.dump(db, f, indent=2)
60
+
61
+ def extract_query_info(query: str) -> Dict:
62
+ """
63
+ Extract intent and date range from user query using LLM
64
+ """
65
+ today_str = datetime.today().strftime("%d-%b-%Y")
66
+
67
+ system_prompt = f"""
68
+ You are an email query parser. Today is {today_str}.
69
+
70
+ Given a user query, extract:
71
+ 1. sender_intent: The person/entity they want emails from (could be name or email)
72
+ 2. start_date and end_date: Date range in DD-MMM-YYYY format
73
+
74
+ For relative dates:
75
+ - "last week" = 7 days ago to today
76
+ - "yesterday" = yesterday only
77
+ - "last month" = 30 days ago to today
78
+ - "last 3 days" = 3 days ago to today
79
+
80
+ Examples:
81
+ - "emails from dev agarwal last week" → sender_intent: "dev agarwal"
82
+ - "show amazon emails from last month" → sender_intent: "amazon"
83
+ - "emails from [email protected] yesterday" → sender_intent: "[email protected]"
84
+
85
+ Return ONLY valid JSON:
86
+ {{
87
+ "sender_intent": "extracted name or email",
88
+ "start_date": "DD-MMM-YYYY",
89
+ "end_date": "DD-MMM-YYYY"
90
+ }}
91
+ """
92
+
93
+ messages = [
94
+ {"role": "system", "content": system_prompt},
95
+ {"role": "user", "content": query}
96
+ ]
97
+
98
+ result = _llm(messages)
99
+ return json.loads(result)
100
+
101
+ def resolve_sender_email(sender_intent: str) -> Tuple[Optional[str], bool]:
102
+ """
103
+ Resolve sender intent to actual email address
104
+ Returns: (email_address, needs_user_input)
105
+ """
106
+ # Check if it's already an email address
107
+ if "@" in sender_intent:
108
+ return sender_intent.lower(), False
109
+
110
+ # Load name mapping
111
+ name_mapping = _load_name_mapping()
112
+
113
+ # Normalize the intent (lowercase for comparison)
114
+ normalized_intent = sender_intent.lower().strip()
115
+
116
+ # Check direct match
117
+ if normalized_intent in name_mapping:
118
+ return name_mapping[normalized_intent], False
119
+
120
+ # Check partial matches (fuzzy matching)
121
+ for name, email in name_mapping.items():
122
+ if normalized_intent in name.lower() or name.lower() in normalized_intent:
123
+ return email, False
124
+
125
+ # No match found
126
+ return None, True
127
+
128
+ def store_name_email_mapping(name: str, email: str):
129
+ """Store new name to email mapping"""
130
+ name_mapping = _load_name_mapping()
131
+ name_mapping[name.lower().strip()] = email.lower().strip()
132
+ _save_name_mapping(name_mapping)
133
+
134
+ def parse_email_query(query: str) -> Dict:
135
+ """
136
+ Main function to parse email query
137
+ Returns structured response with next steps
138
+ """
139
+ try:
140
+ # Step 1: Extract intent and dates
141
+ query_info = extract_query_info(query)
142
+ sender_intent = query_info["sender_intent"]
143
+ start_date = query_info["start_date"]
144
+ end_date = query_info["end_date"]
145
+
146
+ # Step 2: Resolve sender email
147
+ email_address, needs_input = resolve_sender_email(sender_intent)
148
+
149
+ if needs_input:
150
+ # Need to ask user for email address
151
+ return {
152
+ "status": "need_email_input",
153
+ "sender_intent": sender_intent,
154
+ "start_date": start_date,
155
+ "end_date": end_date,
156
+ "message": f"I don't have an email address for '{sender_intent}'. Please provide the email address."
157
+ }
158
+ else:
159
+ # Ready to proceed with email scraping
160
+ return {
161
+ "status": "ready_to_scrape",
162
+ "sender_intent": sender_intent,
163
+ "resolved_email": email_address,
164
+ "start_date": start_date,
165
+ "end_date": end_date,
166
+ "message": f"Found email: {email_address} for '{sender_intent}'"
167
+ }
168
+
169
+ except Exception as e:
170
+ return {
171
+ "status": "error",
172
+ "error": str(e),
173
+ "message": "Failed to parse query"
174
+ }
175
+
176
+ # Test the parser
177
+ if __name__ == "__main__":
178
+ # Test cases
179
+ test_queries = [
180
+ "Show me emails from dev agarwal last week",
181
+ "emails from amazon in the last month",
182
+ "get [email protected] emails yesterday",
183
+ "emails from new person last 3 days"
184
+ ]
185
+
186
+ for query in test_queries:
187
+ print(f"\nQuery: {query}")
188
+ result = parse_email_query(query)
189
+ print(f"Result: {json.dumps(result, indent=2)}")
server/routes.py ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ FastAPI Routes for Email Query System
4
+ """
5
+
6
+ from fastapi import APIRouter, HTTPException
7
+ from pydantic import BaseModel, EmailStr
8
+ from typing import List, Dict, Optional
9
+ import json
10
+
11
+ # Import our modules
12
+ from query_parser import parse_email_query, store_name_email_mapping
13
+ from email_scraper import scrape_emails_from_sender
14
+
15
+ router = APIRouter()
16
+
17
+ # Pydantic models
18
+ class NaturalQuery(BaseModel):
19
+ query: str
20
+
21
+ class EmailMappingInput(BaseModel):
22
+ name: str
23
+ email: EmailStr
24
+
25
+ class EmailResponse(BaseModel):
26
+ date: str
27
+ time: str
28
+ subject: str
29
+ content: str
30
+ message_id: str
31
+
32
+ class QueryParseResponse(BaseModel):
33
+ status: str
34
+ sender_intent: Optional[str] = None
35
+ resolved_email: Optional[str] = None
36
+ start_date: Optional[str] = None
37
+ end_date: Optional[str] = None
38
+ message: str
39
+ error: Optional[str] = None
40
+
41
+ class EmailsResponse(BaseModel):
42
+ status: str
43
+ sender_intent: str
44
+ resolved_email: str
45
+ start_date: str
46
+ end_date: str
47
+ total_emails: int
48
+ emails: List[EmailResponse]
49
+ message: str
50
+
51
+ @router.post("/parse_query", response_model=QueryParseResponse)
52
+ def parse_email_query_endpoint(input_data: NaturalQuery):
53
+ """
54
+ Parse natural language query to extract intent and dates
55
+ """
56
+ try:
57
+ result = parse_email_query(input_data.query)
58
+ return QueryParseResponse(**result)
59
+ except Exception as e:
60
+ raise HTTPException(status_code=400, detail=f"Query parsing failed: {str(e)}")
61
+
62
+ @router.post("/add_email_mapping")
63
+ def add_email_mapping(mapping: EmailMappingInput):
64
+ """
65
+ Add new name to email mapping
66
+ """
67
+ try:
68
+ store_name_email_mapping(mapping.name, mapping.email)
69
+ return {
70
+ "status": "success",
71
+ "message": f"Mapping added: '{mapping.name}' → '{mapping.email}'"
72
+ }
73
+ except Exception as e:
74
+ raise HTTPException(status_code=400, detail=f"Failed to add mapping: {str(e)}")
75
+
76
+ @router.post("/get_emails", response_model=EmailsResponse)
77
+ def get_emails_from_query(input_data: NaturalQuery):
78
+ """
79
+ Complete flow: Parse query → Resolve email → Scrape emails
80
+ """
81
+ try:
82
+ # Step 1: Parse the query
83
+ parsed_result = parse_email_query(input_data.query)
84
+
85
+ if parsed_result["status"] == "need_email_input":
86
+ raise HTTPException(
87
+ status_code=400,
88
+ detail={
89
+ "type": "need_email_input",
90
+ "sender_intent": parsed_result["sender_intent"],
91
+ "message": parsed_result["message"]
92
+ }
93
+ )
94
+ elif parsed_result["status"] == "error":
95
+ raise HTTPException(status_code=400, detail=parsed_result["message"])
96
+
97
+ # Step 2: Scrape emails
98
+ emails = scrape_emails_from_sender(
99
+ parsed_result["resolved_email"],
100
+ parsed_result["start_date"],
101
+ parsed_result["end_date"]
102
+ )
103
+
104
+ # Step 3: Format response
105
+ email_responses = [
106
+ EmailResponse(
107
+ date=email["date"],
108
+ time=email["time"],
109
+ subject=email["subject"],
110
+ content=email["content"],
111
+ message_id=email["message_id"]
112
+ )
113
+ for email in emails
114
+ ]
115
+
116
+ return EmailsResponse(
117
+ status="success",
118
+ sender_intent=parsed_result["sender_intent"],
119
+ resolved_email=parsed_result["resolved_email"],
120
+ start_date=parsed_result["start_date"],
121
+ end_date=parsed_result["end_date"],
122
+ total_emails=len(emails),
123
+ emails=email_responses,
124
+ message=f"Found {len(emails)} emails from {parsed_result['resolved_email']}"
125
+ )
126
+
127
+ except HTTPException:
128
+ raise
129
+ except Exception as e:
130
+ raise HTTPException(status_code=500, detail=f"Email retrieval failed: {str(e)}")
131
+
132
+ @router.get("/view_mappings")
133
+ def view_name_mappings():
134
+ """
135
+ View all stored name to email mappings
136
+ """
137
+ try:
138
+ from query_parser import _load_name_mapping
139
+ mappings = _load_name_mapping()
140
+ return {
141
+ "status": "success",
142
+ "total_mappings": len(mappings),
143
+ "mappings": mappings
144
+ }
145
+ except Exception as e:
146
+ raise HTTPException(status_code=500, detail=f"Failed to load mappings: {str(e)}")
147
+
148
+ @router.get("/health")
149
+ def health_check():
150
+ """
151
+ Health check endpoint
152
+ """
153
+ return {
154
+ "status": "healthy",
155
+ "message": "Email query system is running"
156
+ }
157
+
158
+ # For testing - manual endpoint to add mapping and then query
159
+ @router.post("/complete_flow")
160
+ def complete_email_flow(input_data: dict):
161
+ """
162
+ Test endpoint for complete flow with optional mapping
163
+ Expected input:
164
+ {
165
+ "query": "emails from john last week",
166
+ "mapping": {"name": "john", "email": "[email protected]"} # optional
167
+ }
168
+ """
169
+ try:
170
+ query = input_data.get("query")
171
+ mapping = input_data.get("mapping")
172
+
173
+ if not query:
174
+ raise HTTPException(status_code=400, detail="Query is required")
175
+
176
+ # Add mapping if provided
177
+ if mapping:
178
+ store_name_email_mapping(mapping["name"], mapping["email"])
179
+
180
+ # Parse and get emails
181
+ parsed_result = parse_email_query(query)
182
+
183
+ if parsed_result["status"] == "need_email_input":
184
+ return {
185
+ "status": "need_mapping",
186
+ "message": parsed_result["message"],
187
+ "sender_intent": parsed_result["sender_intent"]
188
+ }
189
+
190
+ # Get emails
191
+ emails = scrape_emails_from_sender(
192
+ parsed_result["resolved_email"],
193
+ parsed_result["start_date"],
194
+ parsed_result["end_date"]
195
+ )
196
+
197
+ return {
198
+ "status": "success",
199
+ "query": query,
200
+ "parsed": parsed_result,
201
+ "total_emails": len(emails),
202
+ "emails": emails[:5] # Return first 5 emails
203
+ }
204
+
205
+ except Exception as e:
206
+ raise HTTPException(status_code=500, detail=str(e))