Sharathhebbar24 commited on
Commit
7fd77fe
·
verified ·
1 Parent(s): 1103c9d

Create main.py

Browse files
Files changed (1) hide show
  1. main.py +226 -0
main.py ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+
3
+ import gradio as gr
4
+
5
+ import uvicorn
6
+
7
+ from fastapi import FastAPI, WebSocket, HTTPException, Depends
8
+
9
+ from pydantic import BaseModel
10
+
11
+ from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Text
12
+ from sqlalchemy.orm import declarative_base, sessionmaker, relationship, Session
13
+
14
+ import secrets
15
+
16
+
17
+ app = FastAPI(title="Pushover Clone")
18
+
19
+ # Database setup
20
+ DATABASE_URL = "sqlite:///./pushover_clone.db"
21
+ engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
22
+ SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)
23
+ Base = declarative_base()
24
+
25
+ # Models
26
+ class User(Base):
27
+ __tablename__ = "users"
28
+ id = Column(Integer, primary_key=True, index=True)
29
+ username = Column(String, unique=True, index=True)
30
+ token = Column(String, unique=True, index=True)
31
+
32
+ notifications = relationship("Notification", back_populates="recipient")
33
+
34
+ class Notification(Base):
35
+ __tablename__ = "notifications"
36
+ id = Column(Integer, primary_key=True, index=True)
37
+ title = Column(String)
38
+ message = Column(Text)
39
+ user_id = Column(Integer, ForeignKey("users.id"))
40
+
41
+ recipient = relationship("User", back_populates="notifications")
42
+
43
+ Base.metadata.create_all(bind=engine)
44
+
45
+ # Dependency
46
+ def get_db():
47
+ db = SessionLocal()
48
+ try:
49
+ yield db
50
+ finally:
51
+ db.close()
52
+
53
+ # Schemas
54
+ class RegisterUser(BaseModel):
55
+ username: str
56
+
57
+ class PushMessage(BaseModel):
58
+ token: str
59
+ title: str
60
+ message: str
61
+
62
+
63
+ @app.post("/register_user")
64
+ def register_user(payload: RegisterUser, db: Session = Depends(get_db)):
65
+ token = secrets.token_hex(16)
66
+ user = User(username=payload.username, token=token)
67
+ db.add(user)
68
+ db.commit()
69
+ db.refresh(user)
70
+ return {"username": user.username, "token": user.token}
71
+
72
+ @app.post("/notify")
73
+ def send_notification(payload: PushMessage, db: Session = Depends(get_db)):
74
+ user = db.query(User).filter(User.token == payload.token).first()
75
+ if not user:
76
+ raise HTTPException(status_code=403, detail="Invalid token")
77
+ notif = Notification(title=payload.title, message=payload.message, recipient=user)
78
+ db.add(notif)
79
+ db.commit()
80
+ return {"status": "queued", "user": user.username}
81
+
82
+ @app.get("/notifications/{username}")
83
+ def get_notifications(username: str, db: Session = Depends(get_db)):
84
+ user = db.query(User).filter(User.username == username).first()
85
+ if not user:
86
+ raise HTTPException(status_code=404, detail="User not found")
87
+ notes = [{"title": n.title, "message": n.message} for n in user.notifications]
88
+ return {"notifications": notes}
89
+
90
+ @app.websocket("/ws/{username}")
91
+ async def websocket_notifications(ws: WebSocket, username: str, db: Session = Depends(get_db)):
92
+ await ws.accept()
93
+ user = db.query(User).filter(User.username == username).first()
94
+ if not user:
95
+ await ws.send_text("User not found")
96
+ await ws.close()
97
+ return
98
+
99
+ await ws.send_text(f"Connected to {username}'s notification stream")
100
+
101
+ # Keep connection open (simplified)
102
+ while True:
103
+ db = SessionLocal()
104
+ user = db.query(User).filter(User.username == username).first()
105
+ if user and user.notifications:
106
+ last = user.notifications[-1]
107
+ await ws.send_json({"title": last.title, "message": last.message})
108
+ await ws.receive_text() # wait for client ping
109
+
110
+ """
111
+ APIs for Gradio Interfaces
112
+ """
113
+ def register_user(username):
114
+ url = "http://127.0.0.1:8080/register_user"
115
+ response = requests.post(url, json={"username": username})
116
+ if response.status_code != 200:
117
+ return f"Failed to register user. Status code: {response.status_code}", ""
118
+ return response.json().get("username", ""), response.json().get("token", "")
119
+
120
+ def send_notification(token, title, message):
121
+ url = "http://127.0.0.1:8080/notify"
122
+ response = requests.post(url, json={"token": token, "title": title, "message": message})
123
+ if response.status_code != 200:
124
+ return f"Failed to send notification. Status code: {response.status_code}"
125
+ return f"Notification sent to user with token ending in ...{token[-4:]}"
126
+
127
+ def get_notifications(username):
128
+ url = f"http://127.0.0.1:8080/notifications/{username}"
129
+ response = requests.get(url)
130
+ if response.status_code != 200:
131
+ return f"Failed to send notification. Status code: {response.status_code}", ""
132
+ title = f"# {response.json()['notifications'][0]['title']}"
133
+ notification = response.json()['notifications'][0]['message']
134
+ return title, notification
135
+
136
+
137
+ """
138
+ Gradio Interfaces
139
+ """
140
+
141
+ def NavBar():
142
+ gr.HTML(
143
+ """
144
+ <nav style="
145
+ background: #4f46e5;
146
+ padding: 12px 24px;
147
+ display: flex;
148
+ justify-content: space-between;
149
+ align-items: center;
150
+ color: white;
151
+ font-family: sans-serif;">
152
+
153
+ <div style='font-weight: bold; font-size: 20px; style="color:white;"'>
154
+ PushOver Notifier
155
+ </div>
156
+
157
+ <div style="display: flex; gap: 20px; font-size: 16px;">
158
+ <a href="/register_new_user/" style="color:white; text-decoration:none;">Register New User</a>
159
+ <a href="/notify_users_device/" style="color:white; text-decoration:none;">Notify Users</a>
160
+ <a href="/get_notifications_page/" style="color:white; text-decoration:none;">Notifications</a>
161
+ </div>
162
+ </nav>
163
+ """
164
+ )
165
+
166
+
167
+
168
+ with gr.Blocks() as register_new_user:
169
+ NavBar()
170
+ gr.Markdown("## Register User")
171
+ register_username = gr.Textbox(label="Enter Username")
172
+ register_button = gr.Button("Register")
173
+ your_username = gr.Textbox(label="Your Username", interactive=False)
174
+ created_token = gr.Textbox(label="Your Token", interactive=False, type="password", show_copy_button=True)
175
+ register_button.click(
176
+ register_user,
177
+ inputs=[register_username],
178
+ outputs=[your_username, created_token],
179
+ )
180
+
181
+
182
+ with gr.Blocks() as notify_users_device:
183
+ NavBar()
184
+ gr.Markdown("## Send Push Notification")
185
+ token = gr.Textbox(label="Enter your Token", type="password")
186
+ title = gr.Textbox(label="Enter Notification Title")
187
+ message = gr.Textbox(label="Enter Notification Message")
188
+ submit = gr.Button("Send Notification")
189
+ alert = gr.Textbox(label="Alert", interactive=False)
190
+ submit.click(
191
+ send_notification,
192
+ inputs=[token, title, message],
193
+ outputs=[alert],
194
+ )
195
+
196
+ with gr.Blocks() as get_notifications_page:
197
+ NavBar()
198
+ gr.Markdown("## Notifications")
199
+ username = gr.Textbox(label="Enter your Username")
200
+ submit = gr.Button("Submit")
201
+ gr.Markdown("### Latest Notification")
202
+ title = gr.Markdown(label="title")
203
+ notification = gr.Markdown(label="Notification")
204
+ submit.click(
205
+ get_notifications,
206
+ inputs=[username],
207
+ outputs=[title, notification],
208
+ )
209
+
210
+ with gr.Blocks() as demo:
211
+ NavBar()
212
+ gr.Image(
213
+ value="./background.png",
214
+ show_label=False,
215
+ elem_classes="full-img",
216
+ )
217
+
218
+ app = gr.mount_gradio_app(app, register_new_user, path="/register_new_user")
219
+ app = gr.mount_gradio_app(app, notify_users_device, path="/notify_users_device")
220
+ app = gr.mount_gradio_app(app, get_notifications_page, path="/get_notifications_page")
221
+
222
+ app = gr.mount_gradio_app(app, demo, path="/")
223
+
224
+ if __name__ == "__main__":
225
+ uvicorn.run(app, host="0.0.0.0", port=7860)
226
+