mirror of
https://github.com/YunoHost-Apps/minchat_ynh.git
synced 2024-09-03 19:36:29 +02:00
Creation
This commit is contained in:
parent
8bd60d3aba
commit
2d3d716f61
15 changed files with 638 additions and 0 deletions
21
LICENSE.txt
Normal file
21
LICENSE.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Chtixof
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
18
README.md
Normal file
18
README.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# minchat_ynh : minchat for Yunohost
|
||||||
|
|
||||||
|
minchat_ynh is a free minimalist chat application packaged for [Yunohost](https://yunohost.org).
|
||||||
|
It is based on [wojtek77/chat](https://github.com/wojtek77/chat), itself based on [Gabriel Nava's tutorial](http://code.tutsplus.com/tutorials/how-to-create-a-simple-web-based-chat-application--net-5931).
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- No need for users to register. Just need the web address.
|
||||||
|
- On connection, the page is feeded with the 50 last messages.
|
||||||
|
- Optional *get* arguments to specify the user name and the room. Example : ...minchat/?name=John&room=Living
|
||||||
|
- Mono room (for now)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
### On Yunohost
|
||||||
|
Via the admin web console, type in: <https://github.com/chtixof/minchat_ynh>
|
||||||
|
Or on ssh : `sudo yunohost app install https://github.com/chtixof/minchat_ynh`
|
||||||
|
### Otherwise
|
||||||
|
Download, unzip and just copy the content of the `source` folder to any folder of your web site.
|
18
conf/nginx.conf
Normal file
18
conf/nginx.conf
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
location PATHTOCHANGE {
|
||||||
|
|
||||||
|
alias WWWPATH ;
|
||||||
|
|
||||||
|
index index.html index.php ;
|
||||||
|
try_files $uri $uri/ index.php;
|
||||||
|
location ~ [^/]\.php(/|$) {
|
||||||
|
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||||
|
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_param REMOTE_USER $remote_user;
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Include SSOWAT user panel.
|
||||||
|
include conf.d/yunohost_panel.conf.inc;
|
||||||
|
}
|
39
manifest.json
Normal file
39
manifest.json
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"name": "minchat",
|
||||||
|
"id": "minchat",
|
||||||
|
"description": {
|
||||||
|
"en": "A minimalist web chat",
|
||||||
|
"fr": "Un web chat minimaliste"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"developer": {
|
||||||
|
"name": "chtixof"
|
||||||
|
},
|
||||||
|
"multi_instance": "false",
|
||||||
|
"arguments": {
|
||||||
|
"install" : [ {
|
||||||
|
"name": "domain",
|
||||||
|
"ask": {
|
||||||
|
"en": "Choose a domain for minchat",
|
||||||
|
"en": "Choisissez un domaine pour minchat"
|
||||||
|
},
|
||||||
|
"example": "domain.org"
|
||||||
|
},{
|
||||||
|
"name": "path",
|
||||||
|
"ask": {
|
||||||
|
"en": "Choose a path for minchat",
|
||||||
|
"en": "Choisissez un chemin pour minchat"
|
||||||
|
},
|
||||||
|
"example": "/minchat",
|
||||||
|
"default": "/minchat"
|
||||||
|
},{
|
||||||
|
"name": "ispublic",
|
||||||
|
"ask": {
|
||||||
|
"en": "Is it a public site (Y)",
|
||||||
|
"en": "Taper Y si le site est public"
|
||||||
|
},
|
||||||
|
"example": "Y",
|
||||||
|
"default": "Y"
|
||||||
|
} ]
|
||||||
|
}
|
||||||
|
}
|
15
scripts/backup
Normal file
15
scripts/backup
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
app=minchat
|
||||||
|
|
||||||
|
# The parameter $1 is the backup directory location
|
||||||
|
# which will be compressed afterward
|
||||||
|
backup_dir=$1/apps/$app
|
||||||
|
mkdir -p $backup_dir
|
||||||
|
|
||||||
|
# Backup sources & data
|
||||||
|
sudo cp -a /var/www/$app/. $backup_dir/sources
|
||||||
|
|
||||||
|
# Copy Nginx and YunoHost parameters to make the script "standalone"
|
||||||
|
sudo cp -a /etc/yunohost/apps/$app/. $backup_dir/yunohost
|
||||||
|
domain=$(sudo yunohost app setting $app domain)
|
||||||
|
sudo cp -a /etc/nginx/conf.d/$domain.d/$app.conf $backup_dir/nginx.conf
|
35
scripts/install
Normal file
35
scripts/install
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Installation de minchat dans Yunohost
|
||||||
|
app=minchat
|
||||||
|
|
||||||
|
# Retrieve arguments
|
||||||
|
domain=$1
|
||||||
|
path=$2
|
||||||
|
is_public=$3
|
||||||
|
|
||||||
|
# Check domain/path availability
|
||||||
|
sudo yunohost app checkurl $domain$path -a $app
|
||||||
|
if [[ ! $? -eq 0 ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy files to the right place with the right permissions
|
||||||
|
final_path=/var/www/$app
|
||||||
|
sudo mkdir -p $final_path
|
||||||
|
sudo cp -a ../sources/* $final_path
|
||||||
|
sudo chown -R www-data: $final_path
|
||||||
|
|
||||||
|
# Modify Nginx configuration file and copy it to Nginx conf directory
|
||||||
|
sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf
|
||||||
|
sed -i "s@WWWPATH@$final_path@g" ../conf/nginx.conf
|
||||||
|
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
|
|
||||||
|
# Make it public is required
|
||||||
|
if [[ $is_public =~ ^[Yy]$ ]]
|
||||||
|
then
|
||||||
|
sudo yunohost app setting $app skipped_uris -v "/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Reload nginx and regenerate SSOwat conf
|
||||||
|
sudo service nginx reload
|
||||||
|
sudo yunohost app ssowatconf
|
15
scripts/remove
Normal file
15
scripts/remove
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
app=minchat
|
||||||
|
|
||||||
|
# Retrieve arguments
|
||||||
|
domain=$(sudo yunohost app setting $app domain)
|
||||||
|
|
||||||
|
# Remove sources
|
||||||
|
sudo rm -rf /var/www/$app
|
||||||
|
|
||||||
|
# Remove configuration files
|
||||||
|
sudo rm -f /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
|
|
||||||
|
# Restart services
|
||||||
|
sudo service nginx reload
|
||||||
|
sudo yunohost app ssowatconf
|
16
scripts/restore
Normal file
16
scripts/restore
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
app=minchat
|
||||||
|
|
||||||
|
# The parameter $1 is the uncompressed restore directory location
|
||||||
|
backup_dir=$1/apps/$app
|
||||||
|
|
||||||
|
# Restore sources & data
|
||||||
|
sudo cp -a $backup_dir/sources/. /var/www/$app
|
||||||
|
|
||||||
|
# Restore Nginx and YunoHost parameters
|
||||||
|
sudo cp -a $backup_dir/yunohost/. /etc/yunohost/apps/$app
|
||||||
|
domain=$(sudo yunohost app setting $app domain)
|
||||||
|
sudo cp -a $backup_dir/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
|
|
||||||
|
# Restart webserver
|
||||||
|
sudo service nginx reload
|
24
scripts/upgrade
Normal file
24
scripts/upgrade
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
app=minchat
|
||||||
|
|
||||||
|
# Retrieve arguments
|
||||||
|
domain=$(sudo yunohost app setting $app domain)
|
||||||
|
path=$(sudo yunohost app setting $app path)
|
||||||
|
|
||||||
|
# Remove trailing "/" for next commands
|
||||||
|
path=${path%/}
|
||||||
|
|
||||||
|
# Copy source files
|
||||||
|
final_path=/var/www/$app
|
||||||
|
sudo mkdir -p $final_path
|
||||||
|
sudo cp -a ../sources/* $final_path
|
||||||
|
|
||||||
|
# Modify Nginx configuration file and copy it to Nginx conf directory
|
||||||
|
sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf
|
||||||
|
sed -i "s@WWWPATH@$final_path@g" ../conf/nginx.conf
|
||||||
|
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
|
|
||||||
|
# Restart services
|
||||||
|
sudo service nginx reload
|
||||||
|
sudo yunohost app ssowatconf
|
||||||
|
|
173
sources/index.php
Normal file
173
sources/index.php
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function v($v, $czyscHtmlIExit = false) {
|
||||||
|
if ($czyscHtmlIExit) ob_end_clean();
|
||||||
|
echo '<pre>' . print_r($v, true) . '</pre>';
|
||||||
|
if ($czyscHtmlIExit) exit;
|
||||||
|
}
|
||||||
|
function vv($v, $czyscHtmlIExit = false) {
|
||||||
|
if ($czyscHtmlIExit) ob_end_clean();
|
||||||
|
echo '<pre>';
|
||||||
|
var_dump($v);
|
||||||
|
echo '</pre>';
|
||||||
|
if ($czyscHtmlIExit) exit;
|
||||||
|
}
|
||||||
|
function vvv($var, & $result = null, $is_view = true)
|
||||||
|
{
|
||||||
|
if (is_array($var) || is_object($var)) foreach ($var as $key=> $value) vvv($value, $result[$key], false);
|
||||||
|
else $result = $var;
|
||||||
|
|
||||||
|
if ($is_view) v($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function loginForm() {
|
||||||
|
echo'
|
||||||
|
<div id="loginform">
|
||||||
|
<form action="" method="post">
|
||||||
|
<p>Please enter your name to continue:</p>
|
||||||
|
<label for="name">Name:</label>
|
||||||
|
<input type="text" name="name" id="name"/>
|
||||||
|
<input type="submit" name="enter" id="enter" value="Enter" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSetup($key = null) {
|
||||||
|
$arr = parse_ini_file('setup.ini');
|
||||||
|
return isset($key) ? $arr[$key] : $arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteOldHistory() {
|
||||||
|
$expireHistory = getSetup('expire_history');
|
||||||
|
$expireDate = date('Y-m-d', strtotime("-$expireHistory day"));
|
||||||
|
foreach (glob('./history/*') as $f) {
|
||||||
|
if (basename($f) < $expireDate) {
|
||||||
|
unlink($f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
if (isset($_GET['logout'])) {
|
||||||
|
session_destroy();
|
||||||
|
header("Location: ./"); //Redirect the user
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_REQUEST['name'])) {
|
||||||
|
if ($_REQUEST['name'] != "") {
|
||||||
|
$_SESSION['name'] = stripslashes(htmlspecialchars($_REQUEST['name']));
|
||||||
|
} else {
|
||||||
|
echo '<span class="error">Please type in a name</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isset($_REQUEST['room'])) {
|
||||||
|
$room = $_REQUEST['room'];
|
||||||
|
} else {
|
||||||
|
$room = "";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title>Chat - Customer Module</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="style.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if (!isset($_SESSION['name'])) {
|
||||||
|
loginForm();
|
||||||
|
deleteOldHistory();
|
||||||
|
} else {
|
||||||
|
?>
|
||||||
|
<div id="wrapper">
|
||||||
|
<div id="menu">
|
||||||
|
<p class="welcome">Welcome to the <b><?php echo $room; ?></b> room, <b><?php echo $_SESSION['name']; ?></b></p>
|
||||||
|
<div style="clear:both"></div>
|
||||||
|
</div>
|
||||||
|
<div id="chatbox"><?php
|
||||||
|
?></div>
|
||||||
|
|
||||||
|
<form name="message" action="">
|
||||||
|
<input name="usermsg" type="text" id="usermsg" size="63" autocomplete="off" autofocus/>
|
||||||
|
<input name="submitmsg" type="submit" id="submitmsg" value="Send" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" src="lib/jquery-2.1.3.min.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
// jQuery Document
|
||||||
|
$(document).ready(function() {
|
||||||
|
var id = 'undefined';
|
||||||
|
//If user submits the form
|
||||||
|
$("#submitmsg").click(function() {
|
||||||
|
var clientmsg = $("#usermsg").val();
|
||||||
|
$("#usermsg").val('');
|
||||||
|
$("#usermsg").focus();
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: 'post.php',
|
||||||
|
data: {text: clientmsg},
|
||||||
|
//cache: false,
|
||||||
|
async: false,
|
||||||
|
success: function(data) {
|
||||||
|
loadLog();
|
||||||
|
},
|
||||||
|
error: function(request, status, error) {
|
||||||
|
$("#usermsg").val(clientmsg);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
//Load the file containing the chat log
|
||||||
|
function loadLog() {
|
||||||
|
var oldscrollHeight = $("#chatbox")[0].scrollHeight;
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: 'server.php',
|
||||||
|
data: {id: id},
|
||||||
|
dataType: 'json',
|
||||||
|
//cache: false,
|
||||||
|
async: false,
|
||||||
|
success: function(data) {
|
||||||
|
id = data.id;
|
||||||
|
var html = '';
|
||||||
|
var date;
|
||||||
|
for (var k in data.data.reverse()) {
|
||||||
|
date = new Date(parseInt(data.data[k][0])*1000);
|
||||||
|
date = date.toLocaleTimeString();
|
||||||
|
date = date.replace(/([\d]+\D+[\d]{2})\D+[\d]{2}(.*)/, '$1$2');
|
||||||
|
html = html
|
||||||
|
+"<div class='msgln'>("+date+") <b>"
|
||||||
|
+data.data[k][1]+"</b>: "+data.data[k][2]+"<br></div>";
|
||||||
|
}
|
||||||
|
$("#chatbox").append(html); //Insert chat messages into the #chatbox div
|
||||||
|
var newscrollHeight = $("#chatbox")[0].scrollHeight;
|
||||||
|
if (newscrollHeight > oldscrollHeight) {
|
||||||
|
$("#chatbox").scrollTop($("#chatbox")[0].scrollHeight);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
loadLog();
|
||||||
|
setInterval(loadLog, <?php echo getSetup('interval') ?>); //Reload file every 2.5 seconds
|
||||||
|
|
||||||
|
//If user wants to end session
|
||||||
|
$("#exit").click(function() {
|
||||||
|
var exit = confirm("Are you sure you want to end the session?");
|
||||||
|
if (exit == true) {
|
||||||
|
window.location = 'index.php?logout=true';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</body>
|
||||||
|
</html>
|
4
sources/lib/jquery-2.1.3.min.js
vendored
Normal file
4
sources/lib/jquery-2.1.3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
103
sources/post.php
Normal file
103
sources/post.php
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function v($v, $czyscHtmlIExit = false) {
|
||||||
|
if ($czyscHtmlIExit) ob_end_clean();
|
||||||
|
echo '<pre>' . print_r($v, true) . '</pre>';
|
||||||
|
if ($czyscHtmlIExit) exit;
|
||||||
|
}
|
||||||
|
function vv($v, $czyscHtmlIExit = false) {
|
||||||
|
if ($czyscHtmlIExit) ob_end_clean();
|
||||||
|
echo '<pre>';
|
||||||
|
var_dump($v);
|
||||||
|
echo '</pre>';
|
||||||
|
if ($czyscHtmlIExit) exit;
|
||||||
|
}
|
||||||
|
function vvv($var, & $result = null, $is_view = true)
|
||||||
|
{
|
||||||
|
if (is_array($var) || is_object($var)) foreach ($var as $key=> $value) vvv($value, $result[$key], false);
|
||||||
|
else $result = $var;
|
||||||
|
|
||||||
|
if ($is_view) v($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function getSetup($key = null) {
|
||||||
|
$arr = parse_ini_file('setup.ini');
|
||||||
|
return isset($key) ? $arr[$key] : $arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//$_POST['text'] = 'abc';
|
||||||
|
session_start();
|
||||||
|
if (!isset($_SESSION['name'])) return;
|
||||||
|
$text = isset($_POST['text']) ? $_POST['text'] : '';
|
||||||
|
if ($text === '') return;
|
||||||
|
|
||||||
|
$isApc = extension_loaded('apc');
|
||||||
|
|
||||||
|
$setup = getSetup();
|
||||||
|
$time = time();
|
||||||
|
$date = date('Y-m-d', $time);
|
||||||
|
$uniqid = uniqid();
|
||||||
|
$id = $time.'-'.$uniqid;
|
||||||
|
|
||||||
|
$tmpDir = './tmp/';
|
||||||
|
$historyDir = './history/';
|
||||||
|
|
||||||
|
$tmpFile = $tmpDir.'cache';
|
||||||
|
$historyFile = $historyDir.$date;
|
||||||
|
|
||||||
|
$fh = @fopen($historyFile, 'a');
|
||||||
|
if ($fh === false) {
|
||||||
|
mkdir($historyDir);
|
||||||
|
if (!is_dir($tmpDir)) mkdir($tmpDir);
|
||||||
|
$fh = @fopen($historyFile, 'a');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start semafore */
|
||||||
|
flock($fh, LOCK_EX);
|
||||||
|
|
||||||
|
// data
|
||||||
|
$data = array($id, $_SESSION['name'], stripslashes(htmlspecialchars($text)));
|
||||||
|
|
||||||
|
// write history
|
||||||
|
fwrite($fh, implode('&', $data)."\n");
|
||||||
|
|
||||||
|
// cache
|
||||||
|
if ($isApc) {
|
||||||
|
$cache = apc_fetch('chat');
|
||||||
|
if ($cache === false) {
|
||||||
|
$cache = array();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$cache = @file_get_contents($tmpFile);
|
||||||
|
if ($cache === false) {
|
||||||
|
$cache = array();
|
||||||
|
} else {
|
||||||
|
$cache = unserialize($cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
array_unshift($cache, $data);
|
||||||
|
|
||||||
|
// delete expired cache
|
||||||
|
$expireTime = floor($time - $setup['interval']/1000 - $setup['expire_cache']);
|
||||||
|
foreach (array_reverse($cache,true) as $k => $e) {
|
||||||
|
if ($e[0] < $expireTime) {
|
||||||
|
unset($cache[$k]);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($isApc) {
|
||||||
|
apc_store('chat', $cache);
|
||||||
|
} else {
|
||||||
|
file_put_contents($tmpFile, serialize($cache));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end semafore */
|
||||||
|
flock($fh, LOCK_UN);
|
||||||
|
fclose($fh);
|
77
sources/server.php
Normal file
77
sources/server.php
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function v($v, $czyscHtmlIExit = false) {
|
||||||
|
if ($czyscHtmlIExit) ob_end_clean();
|
||||||
|
echo '<pre>' . print_r($v, true) . '</pre>';
|
||||||
|
if ($czyscHtmlIExit) exit;
|
||||||
|
}
|
||||||
|
function vv($v, $czyscHtmlIExit = false) {
|
||||||
|
if ($czyscHtmlIExit) ob_end_clean();
|
||||||
|
echo '<pre>';
|
||||||
|
var_dump($v);
|
||||||
|
echo '</pre>';
|
||||||
|
if ($czyscHtmlIExit) exit;
|
||||||
|
}
|
||||||
|
function vvv($var, & $result = null, $is_view = true)
|
||||||
|
{
|
||||||
|
if (is_array($var) || is_object($var)) foreach ($var as $key=> $value) vvv($value, $result[$key], false);
|
||||||
|
else $result = $var;
|
||||||
|
|
||||||
|
if ($is_view) v($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//$_POST['id'] = '1305177620-53c14f147c456';
|
||||||
|
if (!isset($_POST['id'])) return;
|
||||||
|
$isApc = extension_loaded('apc');
|
||||||
|
$id = $_POST['id'];
|
||||||
|
$cache = $isApc ? apc_fetch('chat') : @unserialize(file_get_contents('./tmp/cache'));
|
||||||
|
$data = array();
|
||||||
|
if ($id === 'undefined') {
|
||||||
|
$id = empty($cache) ? 0 : $cache[0][0];
|
||||||
|
// first refresh : loads 50 last msg from history
|
||||||
|
$file = './history/'.date('Y-m-d');
|
||||||
|
if (file_exists($file)) {
|
||||||
|
$history = file($file, FILE_IGNORE_NEW_LINES);
|
||||||
|
$history = array_reverse($history);
|
||||||
|
foreach ($history as & $ref) {
|
||||||
|
$ref = explode('&', $ref);
|
||||||
|
}
|
||||||
|
$data = array_slice($history, 0, 50);
|
||||||
|
}
|
||||||
|
} elseif ($id === '0') {
|
||||||
|
if (!empty($cache)) {
|
||||||
|
$id = $cache[0][0];
|
||||||
|
$data = $cache;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$end = end($cache);
|
||||||
|
// read data from cache
|
||||||
|
if ($id >= $end[0]) {
|
||||||
|
foreach ($cache as $k => $c) {
|
||||||
|
if ($c[0] === $id) break;
|
||||||
|
}
|
||||||
|
$data = array_slice($cache, 0, $k);
|
||||||
|
}
|
||||||
|
// read data from history (any problem witch Internet and are delays)
|
||||||
|
else {
|
||||||
|
$date = date('Y-m-d');
|
||||||
|
$history = array();
|
||||||
|
while (($history = array_merge(file('./history/'.$date, FILE_IGNORE_NEW_LINES), $history)) && $history[0] > $id) {
|
||||||
|
$date = date('Y-m-d', strtotime('-1 day', strtotime($date)));
|
||||||
|
if (!file_exists('./history/'.$date)) break;
|
||||||
|
}
|
||||||
|
// prepare history
|
||||||
|
$history = array_reverse($history);
|
||||||
|
foreach ($history as & $ref) {
|
||||||
|
$ref = explode('&', $ref);
|
||||||
|
}
|
||||||
|
// get data
|
||||||
|
foreach ($history as $k => $h) {
|
||||||
|
if ($h[0] === $id) break;
|
||||||
|
}
|
||||||
|
$data = array_slice($history, 0, $k);
|
||||||
|
}
|
||||||
|
$id = $cache[0][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode(array('id' => $id, 'data' => $data));
|
9
sources/setup.ini
Normal file
9
sources/setup.ini
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
; how often get data from serwer
|
||||||
|
interval = 2500 ; in milliseconds
|
||||||
|
|
||||||
|
; extra time for cache when is problem with Internet
|
||||||
|
expire_cache = 60 ; in seconds
|
||||||
|
|
||||||
|
; time for history
|
||||||
|
expire_history = 1 ; in days
|
71
sources/style.css
Normal file
71
sources/style.css
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
|
||||||
|
/* CSS Document */
|
||||||
|
html {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0; }
|
||||||
|
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
font: 100% arial;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0; }
|
||||||
|
|
||||||
|
p, span {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0; }
|
||||||
|
|
||||||
|
form {
|
||||||
|
margin: 10px 50px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background: #FEFFF4;
|
||||||
|
font: 110% arial; }
|
||||||
|
|
||||||
|
input[type=submit] {
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #0000FF;
|
||||||
|
text-decoration: none; }
|
||||||
|
|
||||||
|
a:hover { text-decoration: underline; }
|
||||||
|
|
||||||
|
#wrapper, #loginform {
|
||||||
|
background: #d8d8d8;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loginform { padding-top: 18px; width: 50%; height: auto; padding-top: 1.5em; padding-bottom: 2.5em; }
|
||||||
|
|
||||||
|
#loginform p { margin: 5px; }
|
||||||
|
|
||||||
|
#chatbox {
|
||||||
|
text-align: left;
|
||||||
|
margin: 0 50px;
|
||||||
|
padding: 0.5em 1ex 0.1em;
|
||||||
|
background: #FEFFF4;
|
||||||
|
height: calc(100% - 120px);
|
||||||
|
border: 1px solid #C7C7C7;
|
||||||
|
overflow: auto; }
|
||||||
|
|
||||||
|
#usermsg {
|
||||||
|
width: calc(100% - 100px);
|
||||||
|
padding: 0.5ex;
|
||||||
|
border: 1px solid #C7C7C7; }
|
||||||
|
|
||||||
|
#submit { width: 60px; }
|
||||||
|
|
||||||
|
.error { color: #ff0000; }
|
||||||
|
|
||||||
|
#menu { padding: 12.5px 25px 12.5px 25px; }
|
||||||
|
|
||||||
|
.welcome { float: left; }
|
||||||
|
|
||||||
|
.logout { float: right; }
|
||||||
|
|
||||||
|
.msgln { margin:0 0 2px 0; }
|
Loading…
Reference in a new issue