<?php
/***************************************************************************
* InfoFrame (image generator for digital picture frames)
* Copyright (C) 2009 Tobias Kolb
*
* 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 3 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/
***************************************************************************/
define('MAGPIE_DIR', 'library/magpierss/');
define('MAGPIE_CACHE_DIR', 'cache');
require_once('library/magpierss/rss_parse.inc');
class FeedPlugin implements IPlugin
{
private $dbconn = NULL;
private $config = NULL;
public function __construct($dbconn, $config) {
$this->dbconn = $dbconn;
$this->config = $config;
}
// update all feeds
public function doUpdate() {
// iterate all feeds
$feednumber = 0;
while ($this->config['feed_url_'.++$feednumber])
{
$this->updateFeed($feednumber);
}
}
// update only the feed with the given feed number
private function updateFeed($feednumber) {
// download feeds XML into local files for caching
$feed_url = $this->config['feed_url_'.$feednumber];
if ($feed_url) {
$curl = curl_init();
$file = fopen("cache/feed_".$feednumber.".xml", "w");
if ($file)
{
curl_setopt($curl, CURLOPT_URL, utf8_encode($feed_url));
curl_setopt($curl, CURLOPT_FILE, $file);
curl_exec($curl);
curl_close($curl);
fclose($file);
}
}
}
public function doOutput($image, $style, $updateData, &$yoffset) {
// define styles
$opt_header = array(
'width' => imagesx($image)-290,
'line_height' => 18,
'align' => ALIGN_LEFT
);
$opt_entry = array(
'width' => imagesx($image)-290,
'height' => 12,
'line_height' => 12,
'align' => ALIGN_LEFT,
'word_wrap_hyphen' => '...',
'aggressive_word_wrap' => true,
);
$feednumber = 0;
while ($this->config['feed_url_'.++$feednumber]) {
$filename = 'cache/feed_' . $feednumber . '.xml';
// check for update
if ($updateData || !file_exists($filename))
$this->updateFeed($feednumber);
// read feed
if(file_exists($filename) && (filesize($filename) > 0)) {
$rss_string = file_get_contents($filename);
$rss = new MagpieRSS( $rss_string, 'UTF-8' );
if ( $rss and !$rss->ERROR) {
// filter entries
$itemcount = count($rss->items); // preserve item count, because it will been changed in for-loop
for($i=0; $i<$itemcount; $i++) {
// filter by entry age
if ($this->config['max_age_in_minutes_'.$feednumber]) {
$published = $rss->items[$i]['date_timestamp'];
$timelimit = time()-($this->config['max_age_in_minutes_'.$feednumber]*60);
if ($published < $timelimit) {
unset($rss->items[$i]); // drop entry
continue;
}
}
// filter title
if ($this->config['title_regex_'.$feednumber]) {
$title = ( $rss->items[$i]['title'] );
$regex = ( $this->config['title_regex_'.$feednumber] );
// match
if (preg_match($regex, $title, $matches)) {
// if subpatterns have been matched only return the concatenated submatches
if (count($matches) > 1) {
$new_title = "";
for ($submatch=1; $submatch < count($matches); $submatch++)
$new_title = $new_title . $matches[$submatch];
if ($new_title)
$rss->items[$i]['title'] = $new_title;
}
} else {
unset($rss->items[$i]); // drop entry
continue;
}
}
}
$start=strtotime($this->config['start_time_'.$feednumber]); $stop=strtotime($this->config['stop_time_'.$feednumber]); if ((count($rss->items) > 0) && ( $start < time()) && $stop > time())
{
// print header
$text = $rss->channel['title'];
imagettftextboxopt($image, 18, 0, 50, $yoffset, $style['textcolor'], $style['font'], $text, $opt_header);
$icon = ImageCreateFromPNG ( 'resources/icons/tv.png' );
ImageCopy($image, $icon, 20, $yoffset+2, 0, 0, imagesx($icon), imagesy($icon));
ImageDestroy($icon);
$yoffset += 26;
// print entries
$counter = 0;
foreach ($rss->items as $item ) {
// if max count of displayed entries is reached OR end of screen is reached and more than one items left
// -> cut off and show hint "x more items..."
$counter++;
$rest = (count($rss->items) - $counter) + 1;
$entrylimit = $this->config['max_displayed_items_'.$feednumber];
if ( (($entrylimit) && ($counter > $entrylimit)) || (($yoffset >= (imagesy($image) - 36)) && ($rest > 1)) ) {
$text = "... $rest weitere Elemente";
imagettftextboxopt($image, 14, 0, 24, $yoffset, $style['textcolor'], $style['fontb'], $text, $opt_entry);
$icon = ImageCreateFromPNG ( 'resources/icons/rss.png' );
ImageCopy($image, $icon, 20, $yoffset-2, 0, 0, imagesx($icon), imagesy($icon));
ImageDestroy($icon);
$yoffset += 20;
break;
}
// print entry text
$text = $item['title'];
$text = str_replace("\n", "", $text);
// dirty trick for replacing inch-symbol \xE2\x80\xB3 by nomal " (because not supported by imagettftext)
$text = str_replace("\xE2\x80\xB3", "\"", $text);
$yoffset += imagettftextboxopt($image, 12, 0, 50, $yoffset, $style['textcolor'], $style['font'], $text, $opt_entry);
$yoffset += 4;
}
$yoffset += 8;
}
}
} // file exist
}
// add some space after all feeds has been displayed
$yoffset += 18;
}
}