<?php
/**
*
* @author Benjamin Gillissen <hide@address.com>
*
* **************************************************************
Copyright (C) 2009 Benjamin Gillissen
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details at:
http://www.gnu.org/copyleft/gpl.html
* **************************************************************
*/
class rpc_cache_file {
private static $indexes = Array('date', 'title', 'size');
private static $CACHE;
private $LIST;
public function __construct($conf){
if (!isset(self::$CACHE) ){
configs::set('file_repo', 'cache_rpc', Array('type'=>'local', 'conf'=>configs::get('hellarpc', 'cacheconf')));
self::$CACHE = new file_abstract('cache_rpc');
self::$CACHE->connect();
}
}
//Status
public function set_status($rpc, $status){
$hdl = self::$CACHE->file_open("/status_$rpc",'w+');
if ( FALSE === $hdl ){ return FALSE; }
$status = base64_encode(serialize($status));
$o = self::$CACHE->file_put($hdl, $status);
self::$CACHE->file_close($hdl);
return $o;
}
public function get_status($rpc){
if ( FALSE === self::$CACHE->isfile("/status_$rpc") ){ return FALSE; }
$status = self::$CACHE->readfile("/status_$rpc");
return unserialize(base64_decode($status));
}
public function status_isexpired($rpc, $to){
if ( FALSE === self::$CACHE->isfile("/status_$rpc") ){
return TRUE;
}
clearstatcache();
$last = self::$CACHE->getmtime("/status_$rpc");
$periode = time() - $last;
return ($periode >= $to );
}
public function get_lastreq($rpc){
if ( FALSE === self::$CACHE->isfile("/status_$rpc") ){ return FALSE; }
return self::$CACHE->getmtime("/status_$rpc");
}
public function set_lastbrw($rpc, $time){
$hdl = self::$CACHE->file_open("/browse_$rpc",'w+');
if ( FALSE === $hdl ){ return FALSE; }
$o = self::$CACHE->file_put($hdl, $time);
self::$CACHE->file_close($hdl);
return $o;
}
public function get_lastbrw($rpc){
if ( FALSE === self::$CACHE->isfile("/browse_$rpc") ){ return FALSE; }
return self::$CACHE->readfile("/browse_$rpc");
}
//browser
public function clean_browser($rpc){
$p = '/'.$rpc;
$limit = $this->get_lastbrw($rpc);
//not older than lastbrw or remove ;)
if ( FALSE === self::$CACHE->isdir($p) ){ return FALSE; }
while ( FALSE !== ( $catid = self::$CACHE->readdir($p)) ){
if ( self::$CACHE->isdir("$p/$catid") ){
while ( FALSE !== ( $hash = self::$CACHE->readdir("$p/$catid")) ){
if ( FALSE === ereg("index", $hash) ){
if ( $limit > self::$CACHE->getmtime("$p/$catid/$hash") ){
$data = self::$CACHE->readfile("$p/$catid/$hash");
$data = unserialize(base64_decode($data));
if ( FALSE !== $data ){
echo "--- $p/$catid/$hash [".$data['title']."]\n";
if ( !empty($data['engine']) ){ $this->remove_id($rpc, $data['engine'], $data['id']); }
} else {
echo "--- $p/$catid/$hash\n";
}
self::$CACHE->remove("$p/$catid/$hash");
$this->drop_indexes($rpc, $catid, $hash);
}
}
}
} elseif ( FALSE === ereg("index", $catid) ){
if ( $limit > self::$CACHE->getmtime("$p/$catid") ){
echo "--- $p/$catid\n";
self::$CACHE->remove("$p/$catid");
$this->drop_indexes($rpc, '', $catid);
}
}
}
return TRUE;
}
private function drop_indexes($rpc, $catid, $hash){
$bp = "/$rpc/$catid";
foreach(self::$indexes as $k => $index){
$p = "$bp/index.$index";
$data = self::$CACHE->readfile($p);
if ( FALSE !== $data ){
$data = split("\n", $data);
foreach($data as $k => $line){
if ( !empty($line) ){
$buf = split("{--}", trim($line));
if ( $buf[0] !== $hash ){ $ndata[$buf[0]] = $buf[1]; }
unset($data[$k]);
}
}
unset($data);
}
if ( isset($ndata) ){
foreach($ndata as $hash => $val){ $data[] = $hash.'{--}'.$val; }
if ( isset($data) ){
$data = implode("\n", $data);
$hdl = self::$CACHE->file_open($p, 'w+');
if ( FALSE !== $hdl ){
self::$CACHE->file_put($hdl, $data);
self::$CACHE->file_close($hdl);
}
}
}
}
}
public function hash_iscached($rpc, $catid, $hash){ return self::$CACHE->isfile("/$rpc/$catid/$hash"); }
public function update_item(&$ITEM){
return $this->create_item(&$ITEM);
}
private function create_item(&$ITEM){
$c = $ITEM->get_content();
$data=Array('rpc' =>$ITEM->get_rpc(),
'hash' =>$ITEM->get_hash(),
'catid' =>$ITEM->get_catid(),
'title' =>$ITEM->get_title(),
'data' =>base64_encode(serialize($c)),
'engine'=>$ITEM->get_engine(),
'id' =>$ITEM->get_id(),
'date' =>$ITEM->get_date(),
'size' =>$c['size'],
'time' =>time() );
$p = '/'.$data['rpc'];
if ( FALSE === self::$CACHE->createdir($p, TRUE) ){ return FALSE; }
$p .= '/'.$data['catid'];
if ( FALSE === self::$CACHE->createdir($p, TRUE) ){ return FALSE; }
$hdl = self::$CACHE->file_open("$p/".$data['hash'], 'w+');
if ( FALSE === $hdl ){ return FALSE; }
$buf = base64_encode(serialize($data));
$o = self::$CACHE->file_put($hdl, $buf);
unset($data);
return $o;
}
public function insert_item(&$ITEM){
$o = $this->create_item(&$ITEM);
if ( $o ){
$c = $ITEM->get_content();
$data=Array('rpc' =>$ITEM->get_rpc(),
'catid' =>$ITEM->get_catid(),
'hash' =>$ITEM->get_hash(),
'title' =>$ITEM->get_title(),
'date' =>$ITEM->get_date(),
'size' =>$c['size'],
'engine'=>$ITEM->get_engine(),
'id' =>$ITEM->get_id(),);
unset($c);
foreach(self::$indexes as $k => &$index){
$this->append_to_index($data['rpc'], $data['catid'], $index, $data['hash'], $data[$index]);
}
if ( $data['engine'] != '' AND $data['id'] != '' ){
$this->append_id($data['rpc'], $data['engine'], $data['id']);
}
}
return $o;
}
private function append_id($rpc, $engine, $id){
$p = "/$rpc/index.id";
$ids = self::$CACHE->readfile($p);
$ids = split("\n", trim($ids));
foreach($ids as $k => &$entry){
if ( $entry === "$engine:$id"){ return TRUE; }
}
$ids[count($ids)] = "$engine:$id";
$ids = implode($ids, "\n");
$hdl = self::$CACHE->file_open($p, 'w+');
if ( FALSE === $hdl ){ return FALSE; }
$o = self::$CACHE->file_put($hdl, $ids);
self::$CACHE->file_close($hdl);
return $o;
}
private function remove_id($rpc, $engine, $id){
$p = "/$rpc/index.id";
$ids = self::$CACHE->readfile($p);
$ids = split("\n", trim($ids));
foreach($ids as $k => &$entry){
if ( $entry !== "$engine:$id"){ $nids[] = $entry; }
}
if ( isset($nids) ){
$nids = implode($nids, "\n");
$hdl = self::$CACHE->file_open($p, 'w+');
if ( FALSE === $hdl ){ return FALSE; }
$o = self::$CACHE->file_put($hdl, $nids);
self::$CACHE->file_close($hdl);
return $o;
}
return self::$CACHE->remove($p);
}
private function append_to_index($rpc, $catid, $index, $hash, $val){
$p = "/$rpc/$catid/index.$index";
$hdl = self::$CACHE->file_open($p, 'a');
if ( FALSE === $hdl ){ return FALSE; }
self::$CACHE->file_put($hdl, "$hash{--}$val\n");
self::$CACHE->file_close($hdl);
}
public function listbycat($rpc, $catid, $order, $way){
if ( !isset($this->LIST) ){
$p = "/$rpc/$catid/index.$order";
$data = self::$CACHE->readfile($p);
if ( FALSE === $data ){ return FALSE; }
$data = split("\n", trim($data));
foreach($data as $k => $line){
if ( !empty($line) ){
$buf = split("{--}", trim($line));
$this->LIST[$buf[0]] = $buf[1];
unset($data[$k]);
}
}
unset($data);
if ( !isset($this->LIST) ){ return FALSE; }
if ( $way === 'ASC'){ array_multisort($this->LIST, SORT_ASC); }
if ( $way === 'DESC'){ array_multisort($this->LIST, SORT_DESC); }
}
$hash = key(&$this->LIST);
if ( FALSE === $hash OR empty($hash) ){ unset($this->LIST);return FALSE; }
next(&$this->LIST);
$p = "/$rpc/$catid/$hash";
$data = self::$CACHE->readfile($p);
if ( FALSE === $data ){
errors::raise("data restore failed, $p not found", CORE_LOG_ERROR, 'RPCBRW');
unset($this->LIST);return FALSE;
}
$data = unserialize(base64_decode($data));
if ( FALSE === $data ){ unset($this->LIST);return FALSE; }
return $data;
}
public function idisonrpc($rpc, $engine, $id){
$p = "/$rpc/index.id";
$ids = self::$CACHE->readfile($p);
$ids = split("\n", $ids);
foreach($ids as $k => &$entry){
if ( $entry === "$engine:$id"){ return TRUE; }
}
return FALSE;
//keep ids in an other file, by rpc
}
}