#!/usr/bin/php
#!/usr/bin/php
<?php
die(highlight_file(__FILE__,1));
// ваш ключ openai.com (для примера, буковки изменены):
$AI_API="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";
// титульная страница нынешней Грелки:
$GRELKA='http://www.leningrad.su/makod/texts/k220_competition.htm';
$list='/tmp/grelka.htm';
if(!is_file($list)) file_put_contents($list,file_get_contents($GRELKA));
$s=file_get_contents($list);
$s=wu($s);
$m=explode("<p><center><h4>",$s);
foreach($m as $num=>$l) {
if( preg_match_all("/(\d+)\. \(\d+\) <a href=\"(.+?)\">(.+?)<\/a>/s",$l,$e) ) {
$gd="Группа ".$num;
if(!is_dir($gd)) mkdir($gd);
echo "\n\n === ".$gd;
foreach($e[0] as $i=>$l) {
$nm=$e[1][$i];
$url="http://www.leningrad.su".$e[2][$i];
$name=trim($e[3][$i]);
$to=$gd."/".sprintf("%02d",$nm)." ".$name.".txt";
echo "\n $url [$name] -> ".$to;
if(is_file($to)) $txt=file_get_contents($to);
else {
$txt=file_get_contents($url); // скачать рассказ
$txt=wu(ochictka($txt));
file_put_contents($to,$txt); // записать рассказ
}
say_text($gd."/".sprintf("%02d",$nm)." ".$name,$txt);
}
}
}
function wu($s) { $s=strtr($s,chr(152),'@'); return(iconv("windows-1251","utf-8//IGNORE",$s)); }
function uw($s) { return(iconv("utf-8","windows-1251//IGNORE",$s)); }
function ochictka($s) {
$s=str_replace("\r",'',$s);
$s=str_replace(' ',' ',$s);
$s=str_replace('"','"',$s);
$s=str_ireplace('<p align="justify">','<p>',$s);
$s=str_ireplace('</p>','',$s);
$s=str_ireplace('<p>','',$s);
if(!preg_match("/<hr>.+?<hr>(.+?)<hr>/s",$s,$m)) die("No body!"); $s=$m[1];
if(!preg_match("/<h3><center><b>(.+?)<\/b><\/h3><\/center>(.+?)$/s",$s,$m)) die("No Header!"); $head=$m[1]; $s=$m[2];
return $head."\n\n".$s;
}
function say_text($dir,$s) {
if(!is_dir($dir)) mkdir($dir);
// $p=glob($dir."/*.txt"); foreach($p as $l) @unlink($l);
$s=uw($s);
$LIM=3000; // ограничение по количеству байт в каждом отрезке
// будем разбивать текст на строки, а затем и собирать подходящие порции для озвучки
$u=explode("\n",$s);
$e=array();
for($i=0;$i<sizeof($u);$i++) {
$l=$u[$i];
while(strlen($l)>$LIM) {
$j=$LIM; while($j && !in_array($l[$j],array('.','?','!'))) $j--;
$e[]=substr($l,0,$j+1);
$l=trim(substr($l,$j+1));
}
$e[]=$l;
}
$k=1; $i=0;
while(isset($e[$i])) {
$o=''; while(isset($e[$i]) && strlen($o.$e[$i])<=$LIM) $o.=$e[$i++]."\n";
$out=$dir."/".sprintf("%03d",$k++).".ask.txt";
if(!strlen($o)) break;
echo "\n[$out] (".strlen($o).")--------\n".wu($o);
file_put_contents($out,wu($o));
$ai=str_replace(".txt",".ai.txt",$out);
if(!is_file($ai)) {
$tim=4;
while(1) {
$l=ask_ai(wu($o));
if($l===false) {
echo ' [Err] ';
sleep($tim);
$tim=$tim*2;
continue;
}
file_put_contents($ai,$l);
break;
}
} // say(wu($o),$mp3); // создать очередную порцию mp3
}
// и наконец соберем все куски в единый файл:
$r=glob($dir."/*.ai.txt"); if(!sizeof($r)) return;
$o=''; foreach($r as $n=>$l) {
$x=file_get_contents($l);
$o=$o.(strlen($o)?' ':'').$x;
}
echo $o;
file_put_contents($dir."/rec.txt",$o);
}
function ejs($s) {
return str_replace(
array("\n", "\r", "\u", "\t", "\f", "\b", "/", '"'),
array("\\n", "\\r", "\\u", "\\t", "\\f", "\\b", "\/", '\\'.'"'),
$s
);
}
function ask_ai($text) {
$a='{
"model": "gpt-3.5-turbo-0301",
"messages": [
{"role": "system", "content": "'
."Перескажи на русском языке кратко отрывок фантастического рассказа."
." Учти, что неизвестно, из какого места рассказа взят отрывок, поэтому избегай выражений 'в начале рассказа' и 'в конце рассказа'."
." Вот этот отрывок: ".ejs($text)
.'"}
],
"temperature": 0.0
}';
$ch = curl_init( "https://api.openai.com/v1/chat/completions" );
curl_setopt($ch, CURLOPT_POST ,1);
curl_setopt($ch, CURLOPT_POSTFIELDS , $a);
curl_setopt($ch, CURLOPT_RETURNTRANSFER ,1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"Authorization: Bearer ".$GLOBALS['AI_API']
]);
$b = curl_exec($ch); curl_close($ch);
echo $b;
if( strstr($b,"You exceeded your current quota") ) { die('блять'); }
if( strstr($b,"We could not parse the JSON") ) { die($a); }
if(strstr($b,"Please try again in 20s.")) sleep(20);
$j=json_decode($b); if(!isset($j->choices[0]->message->content)) return false;
return $j->choices[0]->message->content;
}
?>