Skip to content

Commit

Permalink
Add Python desktop application: GUI with and without server support
Browse files Browse the repository at this point in the history
- Implement Python project to receive notifications from the Express server
- Create GUI version with server support
- Add non-GUI version with server support
- Include installation and setup instructions for Python components in README
- Ensure compatibility with React Native mobile app and Express server
  • Loading branch information
sangamprashant committed Aug 11, 2024
1 parent e3c4591 commit 01537dc
Show file tree
Hide file tree
Showing 18 changed files with 573 additions and 210 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
node_modules
.vscode
.venv
.env
.env
dist
build
226 changes: 17 additions & 209 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@

# Desktop Notifier

Desktop Notifier is a project comprising a React Native mobile application, an Express server with WebSocket support, and a Python desktop application. The system is designed to send real-time notifications to desktop applications based on specific project IDs.
Desktop Notifier is a comprehensive project comprising a React Native mobile application, an Express server with WebSocket support, and a Python desktop application. The system is designed to send real-time notifications to desktop applications based on specific project IDs.

This repository consists of five projects:

1. **`:root/index.js`**: An Express server that handles WebSocket connections to send messages.
2. **`:root/desktop-notifier-mobile-app`**: A React Native mobile app that uses the Express server to send messages.
3. **`:root/desktop-notifier-windows/gui_with_server`**: A Python project with a GUI that sends mobile notifications to the desktop.
4. **`:root/desktop-notifier-windows/gui_without_server`**: A Python project with a GUI but without a server.
5. **`:root/desktop-notifier-windows/without_gui_with_server`**: A Python project without a GUI but with a server.

## Features

Expand Down Expand Up @@ -78,7 +86,7 @@ npm start
```bash
cd desktop-notifier-windows
python -m venv env
source env/bin/activate # On Windows, use `env\Scripts\activate`
source env/bin/activate
pip install -r requirements.txt
```

Expand All @@ -103,206 +111,6 @@ python main.py
2. Each desktop application should register with the server using its specific project ID.
3. Notifications sent from the React Native app will be received by the appropriate desktop applications.

## Example

### Sample React Native Code

```javascript
import React, { useState } from "react";
import { View, TextInput, Button, Alert } from "react-native";

const App = () => {
const [title, setTitle] = useState("");
const [message, setMessage] = useState("");
const [projectId, setProjectId] = useState(""); // Add a field for the project ID

const sendNotification = async () => {
try {
const response = await fetch(
"http://localhost:8000/api/send-notification",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title,
message,
projectId, // Include the project ID in the request body
}),
}
);

if (response.ok) {
Alert.alert(
"Notification Sent",
"Your notification has been sent successfully."
);
} else {
Alert.alert("Error", "Failed to send notification.");
}
} catch (error) {
console.error(error);
Alert.alert("Error", "Failed to send notification.");
}
};

return (
<View>
<TextInput
placeholder="Project ID"
value={projectId}
onChangeText={setProjectId}
/>
<TextInput placeholder="Title" value={title} onChangeText={setTitle} />
<TextInput
placeholder="Message"
value={message}
onChangeText={setMessage}
/>
<Button title="Send Notification" onPress={sendNotification} />
</View>
);
};

export default App;
```

### Sample Python Desktop Application Code

```python
import socketio
from plyer import notification as plyer_notification

# Replace with the project ID in the mobile-app
project_id = "1"

# Create a Socket.IO client
sio = socketio.Client()

@sio.event
def connect():
print("Connected to server")
sio.emit('register', {'projectId': project_id})

@sio.event
def disconnect():
print("Disconnected from server")

@sio.on('notification')
def on_notification(data):
title = data.get('title', 'Notification')
msg = data.get('message', '')
plyer_notification.notify(
app_icon="icon.ico", # Replace with your app icon if available
title=title,
message=msg,
app_name='Desktop Notifier',
timeout=10
)

if __name__ == "__main__":
sio.connect('https://desktop-notifier.onrender.com', transports=['websocket'])
sio.wait()
```

### Sample Express Server Code

```javascript
const express = require("express");
const http = require("http");
const socketIo = require("socket.io");
const cors = require("cors");
const path = require("path");

const app = express();
app.use(cors());
app.use(express.json());

const server = http.createServer(app);
const io = socketIo(server, {
cors: {
origin: "*",
methods: ["GET", "POST"],
allowedHeaders: ["Content-Type"],
credentials: true,
},
});

// Store socket associations with project IDs
const projectSockets = {};

io.on("connection", (socket) => {
console.log(`User connected: ${socket.id}`);

socket.on("register", async (data) => {
console.log("Register event received:", data);

if (data.projectId && typeof data.projectId === "string") {
if (!projectSockets[data.projectId]) {
projectSockets[data.projectId] = [];
}
projectSockets[data.projectId].push(socket);
console.log(
`Socket ${socket.id} registered with projectId: ${data.projectId}`
);
} else {
socket.emit("error", "Invalid projectId");
socket.disconnect();
console.log(`Socket ${socket.id} disconnected due to invalid projectId`);
}
});

socket.on("disconnect", () => {
console.log(`User disconnected: ${socket.id}`);
for (const projectId in projectSockets) {
projectSockets[projectId] = projectSockets[projectId].filter(
(s) => s !== socket
);
if (projectSockets[projectId].length === 0) {
delete projectSockets[projectId];
console.log(`No more sockets connected with projectId: ${projectId}`);
}
}
});
});

app.post("/api/notify", (req, res) => {
const { projectId, title, message } = req.body;

if (!projectId || !title || !message) {
return res.status(400).send("Missing projectId, title, or message");
}

const sockets = projectSockets[projectId];
if (sockets && sockets.length > 0) {
sockets.forEach((socket) => {
socket.emit("notification", { title, message });
});
console.log(`Notification sent to projectId: ${projectId}`);
res.status(200).send("Notification sent");
} else {
console.log(`No clients connected with the given projectId: ${projectId}`);
res.status(404).send("No clients connected with the given projectId");
}
});

app.get("/ping", (req, res) => {
console.log("Ping triggered");
res.send("pong");
});

app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "server.html"));
});

server.listen(8000, () => {
console.log("Listening on port 8000");
});

```


## Contributing

Contributions are welcome! Please fork the repository and submit a pull request for any enhancements or bug fixes.
Expand All @@ -319,7 +127,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file

By following this guide, you'll be able to set up and run the Desktop Notifier project, allowing you to send real-time notifications from a React Native app to desktop applications using WebSocket and system notifications.

## Download the Mobile App
## Download the Builds

<p align="center">
<a href="https://github.com/sangamprashant/desktop-notifier/releases">
Expand All @@ -333,14 +141,14 @@ The UI is built using Tailwind CSS with NativeWind for styling.
### General Layout

<div style="display: flex; justify-content: space-between; flex-wrap: wrap;" align="center">
<img src="./assets/1.jpg" style="width: 48%;" alt="Screenshot 2">
<img src="./assets/2.jpg" style="width: 48%;" alt="Screenshot 3">
<img src="./assets/1.jpg" style="width: 48%;" alt="Screenshot 1">
<img src="./assets/2.jpg" style="width: 48%;" alt="Screenshot 2">
</div>
<div style="display: flex; justify-content: space-between; flex-wrap: wrap; margin-top: 10px;" align="center">
<img src="./assets/3.jpg" style="width: 48%;" alt="Screenshot 4">
<img src="./assets/4.jpg" style="width: 48%;" alt="Screenshot 5">
<img src="./assets/3.jpg" style="width: 48%;" alt="Screenshot 3">
<img src="./assets/4.jpg" style="width: 48%;" alt="Screenshot 4">
</div>
<div style="display: flex; justify-content: space-between; flex-wrap: wrap; margin-top: 10px;" align="center">
<img src="./assets/5.jpg" style="width: 48%;" alt="Screenshot 6">
<img src="./assets/5.jpg" style="width: 48%;" alt="Screenshot 5">
</div>
<img src="./assets/6.png" style="width: 100%;" alt="Screenshot 7">
<img src="./assets/6.png" style="width: 100%;" alt="Screenshot 6">
70 changes: 70 additions & 0 deletions desktop-notifier-windows/gui_with_server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Desktop Notifier

Desktop Notifier is a desktop application built with Python's `tkinter` library. It connects to a server using Socket.IO, receives notifications, and displays them on your desktop. Notifications are stored in a list and can be viewed, deleted, or shown as a pop-up message.

## Features

- **Real-time Notifications:** Connect to a server and receive real-time notifications.
- **Custom Notification Display:** Notifications are displayed with a custom title and message.
- **Notification History:** View a list of received notifications, with options to show or delete them.
- **Status Indicator:** Shows connection status to the server (Connected, Disconnected).
- **Icon Support:** Displays a custom icon for the application and notifications.

## Requirements

- Python 3.x
- Required Python packages:
- `tkinter`
- `Pillow`
- `socketio`
- `plyer`

## Installation

1. **Clone the repository:**
```bash
git clone https://github.com/your-username/desktop-notifier.git
cd desktop-notifier
```

2. **Install the required packages:**
```bash
pip install pillow python-socketio plyer websocket-client
```

3. **Run the application:**
```bash
python main.py
```

4. **Build the executable:**
To build the application into a standalone executable, use the following command:
```bash
pyinstaller --onefile --hidden-import=plyer.platforms.win.notification --icon=icon.ico main.py
```
The executable will be created in the `dist/` directory.

## Download

If you don't want to build the application yourself, you can download a pre-built executable from the [Releases](https://github.com/your-username/desktop-notifier/releases) page.
1. **Go to the [Releases](https://github.com/your-username/desktop-notifier/releases) page.**
2. **Download the latest release.**
3. **Run the executable.**
## Usage
1. **Enter Project ID:**
- Input your unique Project ID to connect to the server.
2. **Start Notifier:**
- Click the "Start Notifier" button to connect to the server and start receiving notifications.
3. **Stop Notifier:**
- Click the "Stop Notifier" button to disconnect from the server.
4. **View Notifications:**
- Notifications will appear in the list. You can click "Show" to view a notification or "Delete" to remove it from the list.
## Demo
<img src="./assets/demo.gif" alt="" />
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions desktop-notifier-windows/gui_with_server/for_gui.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pip install pillow python-socketio plyer
File renamed without changes.
Loading

0 comments on commit 01537dc

Please sign in to comment.