Jump to content
SavaSavanovic

Monitor folder on webserver for new files with PHP to RSS feed

Recommended Posts

I tried to solve problem, but without success, so I am here to seek for some help. I have folder on web server, that contains subfolders and pdf files. I need PHP script that monitors folder and subfolders and create XML for RSS feed on site homepage whe new files are added to folders. Site is on local network only, it is not accesible via Internet. I tried number of scripts but without success.  Any advice please?

Share this post


Link to post
Share on other sites

How are new files uploaded? If via PHP then update as and when...

 

If not then you may want to set up a "cron" (crontab) to call apage script which checks the directory.

 

Or, as a RSS request is made do the check? (if the request to update ratio leans towards the request rather than upload then this may waste resources, butif the directory doesn't contain much then its not much of an issue)

Share this post


Link to post
Share on other sites

Files are uploaded from local computer via BitTorrent Sync. I would like to solve problem with some cron script, but I could not find any suitable. Do you have some recommendation please?

Share this post


Link to post
Share on other sites

Since its a local server you could set the cron job manually once and then that'll just use (say) wget to call a page on the server which would do its job.

 

As for crontab details it all depends on what OS you're using.

 

 

 

Incorporating crontab into your website, when I last looked I gave up and wrote my own I think. It went something like using exec() to call crontab without arguments, grabbing the output, then passing it back again with my stuff appended within some special comments that I could grep next time.

 

My lunch is over so here's what I can see as the main test function I did... and it appears I wrote the data to a tempfile and passed that to crontab:

 

function cron_manage($a){
    //    READ EXISTING CONTENTS
    $orig=shell_exec('crontab -l');
    
    //    CHECK FOR OUR TAG & STRIP OUT
    $orig=preg_replace('/#RXCMS_START(.*)#RXCMS_END\n/is', "",$orig);
    
    //    PREPARE OUR STATEMENTS
    $s="#RXCMS_START".PHP_EOL;
    foreach($a as $e){
        $s.="".$e['mins']." ".$e['hours']." ".$e['days']." ".$e['months']." ".$e['weekday']." ".$e['path']." ".PHP_EOL;
    }
    $s.="#RXCMS_END";
    
    //    APPEND
    $s=$orig.$s;
    
    //    WRITE TO TEMP & EXECUTE CRONTAB
    $fn='/tmp/crontab.txt';
    if(file_put_contents($fn, $s.PHP_EOL)===false){
        echo "write failed<br />";
    }else{
        echo exec('crontab '.$fn);
    }
}

Share this post


Link to post
Share on other sites

Oh and here's how I called that:

 

function cron_e($mins,$hours,$days,$months,$weekday,$path){
    return array('mins'=>$mins,'hours'=>$hours,'days'=>$days,'months'=>$months,'weekday'=>$weekday,'path'=>$path);
}

$a=array();
$a[]=cron_e("*","*","*","*","*","/usr/bin/php /var/www/html/tuts/php/cron/handler.php");
//echo $a[0]['mins']."<br />";
cron_manage($a);

 

From looking you'll want to change the "/usr/bin/php /var/www/html/tuts/php/cron/handler.php" to, well whatever / however you want to call your script (i.e. it doesn't need to be on a server, or even PHP)

Share this post


Link to post
Share on other sites

 I think I made a mistake in previous post, my problem is a script that monitors folders for new files, I know how to setup cron to run a script without problem. Server OS is Ubuntu 14.04. For reading PDFs on website I use Cute file browser script, if it is of any help. I need solution for script that scans folders for new files.

Share this post


Link to post
Share on other sites
<?php /* CLASS AUTORSS V 1.0 Autor : Roberto Aleman Email : ventics@gmail.com
This class is to automatic read and show  the files in a directory as rss 2.0 version,
only configure the config.php file with de globals vars and xml and rss versions,
the directory path and put config, callfile and autorss in directory to show at rss channel.
i apply to read a folder of images and show images gallery to rss channel with feedreader. Enjoy!!
GENERAL PUBLIC LICENCE , GPL */
class autorss
{
	public function show($document_type,$path,$xmlversion,$encoding,$rssversion,$atomversion,$title,$homelink,$description,$language,$lastupdate,$callfile,$generator,$permalink,$category)
	{
		header($document_type); // define document type header
		$dir=getcwd(); // get directory where is script
		$dr=@opendir($dir); //asign path to $dr var
		if(!$dr){
			echo "<error/>"; //if error, stop! and exit!
			exit;
		return;
		}
		else
		{ //begin write xml file whith vars
echo "<?xml version='".$xmlversion."' encoding='".$encoding."'?>
<rss version='".$rssversion."' xmlns:atom='".$atomversion."'>
<channel>
<atom:link href='".$path."' rel='self' type='application/rss+xml'/>
<title>".$title."</title>
<link>".$homelink."</link>
<description>".$description."</description>
<language>".$language."</language>
<lastBuildDate>".$lastupdate."</lastBuildDate>
<generator>".$generator."</generator>";
			while (($archivo = readdir($dr)) !== false)
		{
				if($archivo!="autorss.php" AND $archivo!="." AND $archivo!=".." AND $archivo!="error_log" AND $archivo!=$callfile )
				{
				clearstatcache() ;
						$info = lstat($archivo);

echo "
<item>
<title>".$path.$archivo."</title>
<link>".$path.$archivo."</link>
<pubDate>".date('r' ,$info[9])."</pubDate>
<description><![CDATA[<img src=".$path.$archivo."></img><br/>File Size :".$info[7]." Bytes, Modified:".date('r',$info[9])."]]></description>
<guid isPermaLink='".$permalink."'>".$path.$archivo."</guid>
<category domain='".$path."'>".$category."</category>
</item>";
				}
		}
echo "</channel></rss>";
			closedir($dr);
			return;
		}
	}
}
?>

I tried this script, but I am open to any suggestion.

Share this post


Link to post
Share on other sites

Just tried to send you a PM but you not accepting... or not allowed.

 

If no-one else has done this for you by tonight, I'll have a crack. I'm at work and this requires me to spend some time and start a project, which I can't at the moment.

Share this post


Link to post
Share on other sites

Here's a function to return the N latest files in a folder

$dir = "path/to/folder";

$latest = latestFiles($dir, 5);

echo '<pre>',print_r($latest, true),'</pre>';  // view results


function latestFiles($dir, $n)
{
    $files = glob($dir.'/*.*');
    // sort files by date DESC
    usort($files, function($a,$b) {return filemtime($b) - filemtime($a);});
    // return latest n files
    return array_slice($files,0,$n);
}
  • Like 1

Share this post


Link to post
Share on other sites

Just tried to send you a PM but you not accepting... or not allowed.

 

If no-one else has done this for you by tonight, I'll have a crack. I'm at work and this requires me to spend some time and start a project, which I can't at the moment.

I would appreciate that. Thanks in advance.

Share this post


Link to post
Share on other sites

I forgot to say that file and folder names are in cyrillic, if that can be a problem.

I tried this code today:

<?php

$show = 5;

$files = glob( '*.{pdf,txt}', GLOB_BRACE );
usort( $files, create_function('$a, $b', 'return filemtime( $a ) - filemtime( $b );') );

for ( $i = 0; $i < $show; ++$i )
    echo '<a href="', $file = $files[$i], '">', ucfirst( strtolower(substr($file, 0, strpos($file, '.'))) ), '</a> - ', date( 'D, d M y H:i:s', filemtime($file) ), '<br />', "\n";

?>

but it displays only files from folder where script is placed, without files from subfolders. I think it can be used as guide. I tried it with cyrillic filenames, it shows something like "дфдћч" filenames.

Edited by SavaSavanovic

Share this post


Link to post
Share on other sites

I edited previous code like this:

<?php
header('Content-Type: text/html; charset=utf-8');
$show = 5;

$files = glob( '*.{pdf}', GLOB_BRACE );
usort( $files, create_function('$a, $b', 'return filectime( $b ) - filectime( $a );') );

for ( $i = 0; $i < $show; ++$i )
    echo '<a href="', $file = $files[$i], '">', ucfirst( strtolower(substr($file, 0, strpos($file, '.'))) ), '</a> - ', date( ' d M y H:i', filectime($file) ), '<br />', "\n";

?>

I solved problem with cyrillic names, but I could not make it to scan folders recursively for new files and to show file path two folders up from file, such as folder/subfolder/filename.pdf. Any suggestion?

Share this post


Link to post
Share on other sites

I notice you changed

return filemtime( $b ) - filemtime( $a );

to

return filemtime( $a ) - filemtime( $b );

That will now give you the 5 oldest files and not the 5 latest.

 

 

This will retrieve filenames from the folder and all subfolder

$dir = 'path/to/folder';               // set start directory
$show = 5;

$files = array();                      // array to store retrieved filenames
dirList($dir, $files);                 // call the recursive function to get all files
usort( $files, create_function('$a, $b', 'return filemtime( $b ) - filemtime( $a );') );

for ( $i = 0; $i < $show; ++$i )
    echo '<a href="', $file = $files[$i], '">', ucfirst( strtolower(substr($file, 0, strpos($file, '.'))) ), '</a> - ', date( 'D, d M y H:i:s', filemtime($file) ), '<br />', "\n";

    
/*****************************************************************
** function to retrieve files from folder and all subfolders
******************************************************************/
function dirList($dir, &$results, $level=0) {
    $files = glob($dir.'/*');
    foreach ($files as $f) {
        if (is_dir($f)) continue;
        $results[] = $f;
    }
    $files = glob($dir.'/*', GLOB_ONLYDIR);
    foreach ($files as $f) {
        if (is_dir($f)) {
            dirList($f, $results, $level+1);
        }
        
    }
}

Share this post


Link to post
Share on other sites

Script so far looks like this:

<?php
header('Content-Type: text/html; charset=utf-8');
$dir = '/var/www/html/Cute_browser';
$show = 5;

$files = array();
dirList($dir, $files);
usort( $files, create_function('$a, $b', 'return filectime( $b ) - filectime( $a );') );

for ( $i = 0; $i < $show; ++$i )
    echo '<a href="', $file = $files[$i], '">', ucfirst( strtolower(substr($file, 0, strpos($file, '.'))) ), '</a> - ', date( ' d M y H:i', filectime($file) ), '<br />', "\n";
function dirList($dir, &$results, $level=0) {
    $files = glob($dir.'/*');
    foreach ($files as $f) {
        if (is_dir($f)) continue;
        $results[] = $f;
    }
    $files = glob($dir.'/*', GLOB_ONLYDIR);
    foreach ($files as $f) {
        if (is_dir($f)) {
            dirList($f, $results, $level+1);
        }
        
    }
}


?>

it works nicely, just I wanted, but it shows full path of file, and it is too long to display. How can I display only filename and two directories up?

Share this post


Link to post
Share on other sites

try

$file = '/var/www/html/Cute_browser/abc/xyz.pdf';

$shortPath = join('/', array_slice(explode('/', $file),-3));

echo $shortPath;       //--> Cute_browser/abc/xyz.pdf

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.