Exportovanie logov
Na exportovanie logov si vytvoríme samostatný príkaz export. Pri spustení bez parametra príkaz exportuje logy z všetkých kanálov, ktoré ma v databáze. Pri zadaní parametra príkaz exportuje iba logy z kanálu, ktorý dostal v parametri.
<?php
//if ($sender=='VÁŠ_NICK'){
if (preg_match("/^\!export (.*)$/", $message, $match)){
$query = mysql_query("SELECT * FROM `logs` WHERE `channel`='".mysql_real_escape_string($match['1'])."' order by `time`");
$handle=fopen('logs/'.$match[1], 'w');
while ($data=mysql_fetch_array($query)){
if ($data['type']=='JOIN') fwrite($handle, date("H:i", $data['time']).' '.stripslashes($data['nick'])." (".stripslashes($data['msg']).") vstúpil do ".stripslashes($data['channel'])."\n");
if ($data['type']=='PART') fwrite($handle, date("H:i", $data['time']).' '.stripslashes($data['nick'])." opustil ".stripslashes($data['channel'])."\n");
if ($data['type']=='MSG') fwrite($handle, date("H:i", $data['time']).' '.stripslashes($data['nick']).": ".stripslashes($data['msg'])."\n");
if ($data['type']=='ME') fwrite($handle, date("H:i", $data['time'])." * ".stripslashes($data['nick'])." ".stripslashes($data['msg'])."\n");
if ($data['type']=='NICK') fwrite($handle, date("H:i", $data['time']).' '.stripslashes($data['nick'])." si zmenil nick na ".stripslashes($data['msg'])."\n");
if ($data['type']=='QUIT') fwrite($handle, date("H:i", $data['time']).' '.stripslashes($data['nick'])." opustil ".stripslashes($data['channel'])." [".stripslashes($data['msg'])."]\n");
}
fclose($handle);
} else {
$query = mysql_query("SELECT DISTINCT `channel` FROM `logs`");
while ($data=mysql_fetch_array($query)){
unlink('logs/'.$data['channel']);
}
$query = mysql_query("SELECT * FROM `logs` order by `time`");
while ($data=mysql_fetch_array($query)){
$handle=fopen('logs/'.$data['channel'], 'a');
if ($data['type']=='JOIN') fwrite($handle, date("H:i", $data['time']).' '.stripslashes($data['nick'])." (".stripslashes($data['msg']).") vstúpil do ".stripslashes($data['channel'])."\n");
if ($data['type']=='PART') fwrite($handle, date("H:i", $data['time']).' '.stripslashes($data['nick'])." opustil ".stripslashes($data['channel'])."\n");
if ($data['type']=='MSG') fwrite($handle, date("H:i", $data['time']).' '.stripslashes($data['nick']).": ".stripslashes($data['msg'])."\n");
if ($data['type']=='ME') fwrite($handle, date("H:i", $data['time'])." * ".stripslashes($data['nick'])." ".stripslashes($data['msg'])."\n");
if ($data['type']=='NICK') fwrite($handle, date("H:i", $data['time']).' '.stripslashes($data['nick'])." si zmenil nick na ".stripslashes($data['msg'])."\n");
if ($data['type']=='QUIT') fwrite($handle, date("H:i", $data['time']).' '.stripslashes($data['nick'])." opustil ".stripslashes($data['channel'])." [".stripslashes($data['msg'])."]\n");
fclose($handle);
}
}
//}
?>
Namiesto „VÁŠ_NICK“ si v texte doplňte nick, pod ktorým vystupujete na IRC sieti. Je to z dôvodu, aby ostatní užívatelia nemohli zahltiť bota požiadavkami na export databázy. Pri zadávaní parametra dávajte pozor, aby ste nezadali cestu k nejakému existujúcemu súboru, pretože bot ho prepíše. Pri spustené príkazu s parametrom si program vyberie všetky dáta z databázy ktoré majú v stĺpci channel rovnakú hodnotu ako parameter príkazu. Potom dáta postupne zapíše do súboru. Pri spustení príkazu bez parametra najprv vyberieme unikátne hodnoty stĺpca channel, teda zistíme názvy všetkých kanálov, od ktorých máme nejaké dáta a každému z nich vytvoríme súbor pre logy. Potom vyberieme všetky dáta z tabuľky logs zoradené podľa času a postupne ich zapíšeme do súboru, kam patria.
Spúšťanie príkazu v určitý čas
Niekedy možno budeme potrebovať naplánovať spustenie nejakého príkazu v budúcnosti napríklad štatistiky z kanálu na konci dňa, stiahnutie nejakého súboru a pod. Všetky príkazy a čas vykonania budeme ukladať do databázy. Modul sa každú minútu pozrie do databázy, či v túto minútu nemá vykonať nejaký príkaz. Vykonávanie s presnosťou na sekundy nebudeme potrebovať (zbytočne by to zahltilo databázový server pri kontrolovaní príkazov ktoré majú byť vykonané). Najprv vytvoríme tabuľku na uchovávanie naplánovaných príkazov:
CREATE TABLE `spustanie` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`time` varchar(5) NOT NULL,
`channel` varchar(50) NOT NULL,
`command` varchar(100) NOT NULL,
`sender` varchar(50) NOT NULL,
`host` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
)
Ďalej vytvoríme príkaz spusti, ktorý pridá do databázy záznam o príkaze. Najprv si skontrolujeme, či je zadaný existujúci čas a až potom záznam pridáme do databázy. Po úspešnom vložení vypíšeme hlášku pridané.
<?php
if (preg_match("/^\!spusti ([0-2]{1}[0-9]\:[0-6][0-9]) (.*)$/", $message, $match)){
$cas = explode(":", $match[1]);
print_r($cas);
if ($cas[0]<="23" && $cas[0]>="0" && $cas[1]>="0" && $cas[0]<"60"){
if (mysql_query("INSERT INTO `spustanie` (`time`, `command`, `channel`, `sender`, `host`) VALUES ('".mysql_real_escape_string($match[1])."', '".mysql_real_escape_string($match[2])."', '".mysql_real_escape_string($act_chan)."', '".mysql_real_escape_string($sender)."', '".mysql_real_escape_string($host)."')")) sendmsg($act_chan, "pridane");
}
}
?>
Nakoniec samotný modul, ktorý bude spúšťať naplánované príkazy.
<?php
if (!isset($spustanie_cas) || $spustanie_cas<time()){
$q = mysql_query("SELECT * FROM `spustanie` WHERE `time`='".date("H:i")."'");
while ($data = mysql_fetch_array($q)){
$sender_ = $sender;
$host_ = $host;
$msg_ = $msg;
$message_ = $message;
$act_chan_ = $act_chan;
$sender = $data['sender'];
$host = $data['host'];
$message = $data['command'];
$act_chan = $data['channel'];
if (preg_match("/^\!([a-zA-Z]*)/", $message, $match)){
include ('commands/'.$match[1]);
}
$sender = $sender_;
$host = $host_;
$msg = $msg_;
$message = $message_;
$act_chan = $act_chan_;
mysql_query("DELETE FROM `spustanie` WHERE `id`='".mysql_real_escape_string($data['id'])."'");
}
$spustanie_cas = time()+50;
}
?>
Podmienka nám zaručí, že sa kód v module vykoná pri prvom spustení alebo po ubehnutí časového limitu (v našom prípade 50 sekúnd, čo znamená, že sa príkazy ktoré sa majú vykonať budú kontrolovať každých 50 sekúnd). Potom si vyberieme všetky príkazy, ktoré máme spustiť v aktuálnu minútu. Do premennej sender dáme nick užívateľa, ktorý naplánoval spustenie príkazu, do premennej jeho host, do premennej message dáme text zo stĺpca command a do premennej act_chan dáme meno kanálu, v ktorom užívateľ zadal príkaz. Tým napodobíme situáciu, ako keby práve tento užívateľ napísal správu s príkazom. Ak správa obsahuje nejaký príkaz, vykonáme ho a potom vrátime do premenných sender, host, msg, message a act_chan staré hodnoty. Potom vymažeme vykonaný príkaz z databázy a zabezpečíme, aby sa modul spustil až o 50 sekúnd (môžete si doplniť vlastný čas).
Záver
Možno vás zaujíma spôsob, ako si môže bot od užívateľa vypýtať údaje, ktoré potrebuje na vykonanie nejakej operácie. Takéto (interaktívne) programy si ukážeme nabudúce.