#!/usr/bin/env python3
# build_chatapp_pro_files.py
#ٮ"ﺴﺤ"ﻪﺣﺮڡ"ﻪایٮ+يﺎمرﺳﺎنٮ2ﺎPHP + MySQL + WebSocket+ارﺳﺎلڡ"ﺎٮ4ﻞوﻋکﺲ
#ﻣﺴٮ4ﺮٮ+يﺸڡ"ﺮض:/var/www/html/chatapp/
import os
BASE_DIR = "/var/www/html/chatapp"
folders = [
"config",
"public",
"public/js",
"public/css",
"public/uploads",
"server",
"includes",
"sql"
]
for folder in folders:
path = os.path.join(BASE_DIR, folder)
os.makedirs(path, exist_ok=True)
# -----------------------------
# config/config.php
config_php = """<?php
$DB_HOST = 'localhost';
$DB_NAME = 'chatapp';
$DB_USER = 'root';
$DB_PASS = '';
try {
$pdo = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=utf8", $DB_USER, $DB_PASS);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Connection failed: " . $e->getMessage());
}
?>
"""
with open(os.path.join(BASE_DIR, "config/config.php"), "w") as f:
f.write(config_php)
# -----------------------------
# includes/db.php
db_php = """<?php
require_once __DIR__ . '/../config/config.php';
?>
"""
with open(os.path.join(BASE_DIR, "includes/db.php"), "w") as f:
f.write(db_php)
# -----------------------------
# includes/auth.php
auth_php = """<?php
session_start();
require_once 'db.php';
function login($username, $password){
global $pdo;
$stmt = $pdo->prepare("SELECT * FROM users WHERE username=?");
$stmt->execute([$username]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if($user && password_verify($password, $user['password'])){
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
return true;
}
return false;
}
function register($username, $password){
global $pdo;
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("INSERT INTO users (username, password) VALUES (?, ?)");
return $stmt->execute([$username, $hash]);
}
function isLoggedIn(){ return isset($_SESSION['user_id']); }
function currentUserId(){ return $_SESSION['user_id'] ?? 0; }
?>
"""
with open(os.path.join(BASE_DIR, "includes/auth.php"), "w") as f:
f.write(auth_php)
# -----------------------------
# sql/schema.sql
schema_sql = """CREATE DATABASE IF NOT EXISTS chatapp;
USE chatapp;
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
status ENUM('offline','online') DEFAULT 'offline',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS messages (
id INT AUTO_INCREMENT PRIMARY KEY,
sender_id INT NOT NULL,
receiver_id INT DEFAULT NULL,
group_id INT DEFAULT NULL,
message TEXT DEFAULT NULL,
file_path VARCHAR(255) DEFAULT NULL,
file_type VARCHAR(50) DEFAULT NULL,
is_read TINYINT(1) DEFAULT 0,
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (sender_id) REFERENCES users(id)
);
CREATE TABLE IF NOT EXISTS groups (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS group_members (
id INT AUTO_INCREMENT PRIMARY KEY,
group_id INT NOT NULL,
user_id INT NOT NULL,
FOREIGN KEY (group_id) REFERENCES groups(id),
FOREIGN KEY (user_id) REFERENCES users(id)
);
"""
with open(os.path.join(BASE_DIR, "sql/schema.sql"), "w") as f:
f.write(schema_sql)
# -----------------------------
# public/index.php
index_php = """<?php
require_once '../includes/auth.php';
$message = '';
if($_SERVER['REQUEST_METHOD']=='POST'){
if(isset($_POST['login'])){
if(login($_POST['username'], $_POST['password'])){
header('Location: chat.php'); exit;
} else { $message=' ٮ"ﺎمکﺎرٮ2ریٮ4ﺎرﻣﺰﻋٮ2وراﺷٮEٮ2ﺎهاﺳﺖ '; }
} elseif(isset($_POST['register'])){
if(register($_POST['username'], $_POST['password'])){
$message=' ٮHٮ2ﺖٮ"ﺎمﻣﻮڡ"ﻖ!ﺣﺎKواردﺷويﺪ .';
} else { $message=' ﺣ"ﻄﺎدرٮHٮ2ﺖٮ"ﺎمٮ4ﺎٮ"ﺎمکﺎرٮ2ریﻣﻮﺣ2ﻮداﺳﺖ '; }
}
}
?>
<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="UTF-8">
<title> ٮ+يﺎمرﺳﺎنﺣﺮڡ"ﻪای </title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="login-box">
<h2> ورود/ٮHٮ2ﺖٮ"ﺎم </h2>
<form method="POST" enctype="multipart/form-data">
<input type="text" name="username" placeholder=" ٮ"ﺎمکﺎرٮ2ری " required><br>
<input type="password" name="password" placeholder=" رﻣﺰﻋٮ2ور " required><br>
<button name="login"> ورود </button>
<button name="register"> ٮHٮ2ﺖٮ"ﺎم </button>
</form>
<p><?php echo $message; ?></p>
</div>
</body>
</html>
"""
with open(os.path.join(BASE_DIR, "public/index.php"), "w") as f:
f.write(index_php)
# -----------------------------
# public/chat.php
chat_php = """<?php
require_once '../includes/auth.php';
if(!isLoggedIn()){ header('Location: index.php'); exit; }
?>
<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="UTF-8">
<title> ﺣ+ﺖﺣﺮڡ"ﻪای </title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="chat-container">
<div class="sidebar" id="userList"></div>
<div class="chat-window" id="chatWindow"></div>
<input type="text" id="msgInput" placeholder=" ٮ+يﺎمﺣ"ﻮدراٮ2ٮ"ويﺴٮ4ﺪ ">
<input type="file" id="fileInput">
<button id="sendBtn"> ارﺳﺎل </button>
</div>
<script>
const currentUser = '<?php echo $_SESSION["username"]; ?>';
</script>
<script src="js/chat_pro.js"></script>
</body>
</html>
"""
with open(os.path.join(BASE_DIR, "public/chat.php"), "w") as f:
f.write(chat_php)
# -----------------------------
# public/css/style.css
style_css = """body{font-family:sans-serif;background:#f0f0f0;}
.login-box{width:300px;margin:100px auto;padding:20px;background:#fff;border-radius:10px;text-align:center;}
.chat-container{display:flex;width:700px;margin:50px auto;background:#fff;padding:10px;border-radius:10px;}
.sidebar{width:200px;border-right:1px solid #ccc;padding:5px;overflow-y:auto;height:400px;}
.chat-window{flex:1;height:400px;overflow-y:scroll;border:1px solid #ccc;padding:10px;margin-left:10px;}
#msgInput{width:60%;padding:5px;} #fileInput{width:20%;} #sendBtn{padding:5px;}
"""
with open(os.path.join(BASE_DIR, "public/css/style.css"), "w") as f:
f.write(style_css)
# -----------------------------
# public/js/chat_pro.js
chat_js = """let ws = new WebSocket('ws://127.0.0.1:8080/chat');
let chatWindow = document.getElementById('chatWindow');
let userList = document.getElementById('userList');
let sendBtn = document.getElementById('sendBtn');
let msgInput = document.getElementById('msgInput');
let fileInput = document.getElementById('fileInput');
ws.onopen = ()=>{ console.log('WebSocket connected'); };
ws.onmessage = function(event){
let data = JSON.parse(event.data);
if(data.type=='message'){
let msgHtml = '<b>'+data.sender+':</b> '+(data.message||'');
if(data.file_path){
if(data.file_type.startsWith('image')){
msgHtml += '<br><img src="'+data.file_path+'" width="150">';
} else {
msgHtml += '<br><a href="'+data.file_path+'" target="_blank"> داٮ"ﻠﻮدڡ"ﺎٮ4ﻞ </a>';
}
}
chatWindow.innerHTML += '<p>'+msgHtml+'</p>';
chatWindow.scrollTop = chatWindow.scrollHeight;
} else if(data.type=='users'){
userList.innerHTML = '';
data.users.forEach(u=>{
let el = document.createElement('div'); el.textContent = u;
userList.appendChild(el);
});
}
};
sendBtn.onclick = function(){
let msg = msgInput.value.trim();
let file = fileInput.files[0];
if(msg=='' && !file) return;
let formData = new FormData();
formData.append('message', msg);
formData.append('sender', currentUser);
if(file) formData.append('file', file);
fetch('send_message.php', { method:'POST', body: formData });
msgInput.value = '';
fileInput.value = '';
};
"""
with open(os.path.join(BASE_DIR, "public/js/chat_pro.js"), "w") as f:
f.write(chat_js)
# -----------------------------
# public/send_message.php
send_message_php = """<?php
require_once '../includes/auth.php';
require_once '../includes/db.php';
$sender = currentUserId();
$receiver = null;
$message = $_POST['message'] ?? '';
$file_path = null;
$file_type = null;
if(isset($_FILES['file']) && $_FILES['file']['error'] == 0){
$targetDir = '../uploads/';
if(!is_dir($targetDir)) mkdir($targetDir, 0777, true);
$filename = time() . '_' . basename($_FILES['file']['name']);
$targetFile = $targetDir . $filename;
if(move_uploaded_file($_FILES['file']['tmp_name'], $targetFile)){
$file_path = 'uploads/' . $filename;
$file_type = mime_content_type($targetFile);
}
}
$stmt = $pdo->prepare("INSERT INTO messages (sender_id, receiver_id, message, file_path, file_type) VALUES (?,?,?,?,?)");
$stmt->execute([$sender, $receiver, $message, $file_path, $file_type]);
?>
"""
with open(os.path.join(BASE_DIR, "public/send_message.php"), "w") as f:
f.write(send_message_php)
# -----------------------------
# server/WebSocketServer.php
websocket_php = """<?php
require __DIR__ . '/../vendor/autoload.php';
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class ChatServer implements MessageComponentInterface {
protected $clients;
public function __construct(){ $this->clients = new \SplObjectStorage; }
public function onOpen(ConnectionInterface $conn){ $this->clients->attach($conn); }
public function onMessage(ConnectionInterface $from, $msg){
foreach($this->clients as $client){ $client->send($msg); }
}
public function onClose(ConnectionInterface $conn){ $this->clients->detach($conn); }
public function onError(ConnectionInterface $conn, \Exception $e){ $conn->close(); }
}
$server = \Ratchet\Server\IoServer::factory(
new \Ratchet\Http\HttpServer(
new \Ratchet\WebSocket\WsServer(
new ChatServer()
)
), 8080
);
$server->run();
?>
"""
with open(os.path.join(BASE_DIR, "server/WebSocketServer.php"), "w") as f:
f.write(websocket_php)
#print(" ٮ"ﺴﺤ"ﻪﺣﺮڡ"ﻪایٮ+يﺎمرﺳﺎنٮ2ﺎارﺳﺎلڡ"ﺎٮ4ﻞﺳﺎﺣ"ٮEﻪﺷﺪ ")
#print(" ﻣﺴٮ4ﺮٮ+روژه :", BASE_DIR)
#print(" دٮ4ٮEﺎٮ2يﺲ : sql/schema.sql")
#print(" ٮ+ﻮﺷﻪآٮ+ﻠﻮدڡ"ﺎٮ4ﻞﻫﺎ : public/uploads")
#print(" ٮ2رایٮ"ﺼﺐ WebSocket: composer require cboden/ratchet")
#print(" ٮ2رایاﺣ2را : php server/WebSocketServer.php")
print("it don")
