function smarty_modifier_rss_date_parse($rss_date, $default_date = null) { if ($rss_date != '') { return parse_w3cdtf($rss_date); } elseif (isset($default_date) && $default_date != '') { return parse_w3cdtf($default_date); } else { return; } }
/** * Récupère le flux RSS à partir d'une URL. * Utilise MagpieRss http://magpierss.sourceforge.net/ */ public function getRss($url, $nbMax = -1) { $arFeeds = array(); // Test and Create rss temp_dir $cachePath = COPIX_CACHE_PATH . 'fluxrss/'; $cacheTestFile = 'rss.txt'; if (!file_exists($cachePath . $cacheTestFile)) { require_once COPIX_UTILS_PATH . 'CopixFile.class.php'; $objectWriter = new CopixFile(); $objectWriter->write($cachePath . $cacheTestFile, date('Y/m/d H:i')); } // Use Magpie to parse current RSS file define('MAGPIE_CACHE_DIR', COPIX_CACHE_PATH . 'rss'); require_once 'rss_fetch.inc'; $rss = fetch_rss($url); if ($rss) { if ($nbMax > 0) { $arFeeds = array_slice($rss->items, 0, intval($nbMax)); } else { $arFeeds = $rss->items; } } foreach ($arFeeds as $key => $Feed) { //print_r($Feed); if (isset($Feed['dc']['date'])) { $currentDate = @parse_w3cdtf($Feed['dc']['date']); // Ok with dotclear that uses w3c date format //var_dump($currentDate); } else { $currentDate = -1; } if ($currentDate != -1) { $Feed['dc']['datecopix'] = date("Ymd", $currentDate); if (!isset($Feed['date_timestamp'])) { $Feed['date_timestamp'] = $currentDate; } } else { if (isset($Feed['date_timestamp'])) { // Ok with b2evolution that uses timestamp format $Feed['dc']['datecopix'] = date('Ymd', $Feed['date_timestamp']); } else { $Feed['dc']['datecopix'] = null; $Feed['date_timestamp'] = null; } } //var_dump($Feed); //die(); $arFeeds[$key] = $Feed; } return $arFeeds; }
function MagpieRSSDate($item) { # by http://www.pmwiki.org/wiki/Profiles/Mike $date = ""; $rss_2_date = $item['pubdate']; $rss_1_date = $item['dc']['date']; $rss_3_date = $item['prism']['publicationDate']; $atom_date = $item['issued']; if ($atom_date != "") { $date = parse_w3cdtf($atom_date); } if ($rss_1_date != "") { $date = parse_w3cdtf($rss_1_date); } if ($rss_2_date != "") { $date = strtotime($rss_2_date); } if ($rss_3_date != "") { $date = parse_w3cdtf($rss_3_date); } if ($date == '-1') { if ($atom_date != "") { $date = strtotime($atom_date); } if ($rss_1_date != "") { $date = strtotime($rss_1_date); } if ($rss_3_date != "") { $date = strtotime($rss_3_date); } } if ($date != "" && $date != '-1') { $secondsinaday = 60 * 60 * 24; $dateformat = 'd M Y'; $today = time(); $yesterday = time() - $secondsinaday; $datetoday = date($dateformat, $today); $dateyesterday = date($dateformat, $yesterday); $daterss = date($dateformat, $date); if ($daterss == $datetoday || $daterss == $dateyesterday) { $color = 'red'; } else { $color = 'gray'; } return '<div class="magpie-date" style="color:' . $color . '">' . $daterss . '</div>'; } return ''; }
public static function getUnixTimestamp($item) { $rss_2_date = $item['pubdate']; $rss_1_date = $item['dc']['date']; $atom_date = $item['issued']; if ($atom_date != "") { $date = parse_w3cdtf($atom_date); } if ($rss_1_date != "") { $date = parse_w3cdtf($rss_1_date); } if ($rss_2_date != "") { $date = strtotime($rss_2_date); } return $date; }
function rss_fetch_date_format($format, $item) { global $L_DATE_PATTERN; $date = ""; if (isset($item['date_timestamp'])) { $date = date($format, $item['date_timestamp']); } else { if (isset($item['dc']['date'])) { $date = date($format, parse_w3cdtf($item['dc']['date'])); } else { if (isset($item['pubdate'])) { if (preg_match($L_DATE_PATTERN, $item['pubdate'])) { $date = date($format, parse_w3cdtf(conv_date($item['pubdate']))); } else { // "$item['pubdate']"を上で変換出来なかった時はそのまま表示 $date = $item['pubdate']; } } } } return $date; }
$_echo_LT5 = " (LT5!)"; } foreach ($feed->items as $item) { $check_sql = $sql = $ftime = $flink = $ftitle = $fdesc = ''; $we_have_a_date = TRUE; if (@(!($flink = $item['link']))) { $flink = $item['guid']; } $time = dst_test(time()); if (isset($item['pubdate'])) { $stamp = bug_free_strtotime($item['pubdate']); $stamp = dst_test($stamp); $ftime = date("Y-m-d", $stamp) . "T" . date("H:i:s+01:00", $stamp); $_date_from = "pubdate"; } elseif (isset($item['dc']['date'])) { $stamp = parse_w3cdtf($item['dc']['date']); $stamp = dst_test($stamp); $ftime = date("Y-m-d", $stamp) . "T" . date("H:i:s+01:00", $stamp); $_date_from = "dc:date"; } else { $stamp = $time; $ftime = date("Y-m-d", $stamp) . "T" . date("H:i:s+01:00", $stamp); $we_have_a_date = FALSE; $_date_from = "time()"; } if (@(!($ftitle = $item['title']))) { $ftitle = substr(strip_tags($fdesc), 0, 25) . "..."; } $ftitle = str_replace("'", "\\'", $ftitle); if (@(!($fdesc = $item['content']['encoded']))) { if (@(!($fdesc = $item['description']))) {
define('MAGPIE_DIR', '/home/kellan/projs/magpierss/'); require_once MAGPIE_DIR . 'rss_fetch.inc'; require_once MAGPIE_DIR . 'rss_utils.inc'; // optionally show lots of debugging info # define('MAGPIE_DEBUG', 2); // optionally flush cache quickly for debugging purposes, // don't do this on a live site # define('MAGPIE_CACHE_AGE', 10); // use cache? default is yes. see rss_fetch for other Magpie options # define('MAGPIE_CACHE_ON', 1) // setup template object $smarty = new Smarty(); $smarty->compile_check = true; // url of an rss file $url = htmlspecialchars($_GET['rss_url'], ENT_QUOTES); if ($url) { // assign a variable to smarty for use in the template $smarty->assign('rss_url', $url); // use MagpieRSS to fetch remote RSS file, and parse it $rss = fetch_rss($url); // if fetch_rss returned false, we encountered an error if (!$rss) { $smarty->assign('error', magpie_error()); } $smarty->assign('rss', $rss); $item = $rss->items[0]; $date = parse_w3cdtf($item['dc']['date']); $smarty->assign('date', $date); } // parse smarty template, and display using the variables we assigned $smarty->display('simple.smarty');
function update_rss_feed($link, $feed, $ignore_daemon = false, $no_cache = false, $override_url = false) { require_once "lib/simplepie/simplepie.inc"; require_once "lib/magpierss/rss_fetch.inc"; require_once 'lib/magpierss/rss_utils.inc'; $debug_enabled = defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']; if (!$_REQUEST["daemon"] && !$ignore_daemon) { return false; } if ($debug_enabled) { _debug("update_rss_feed: start"); } if (!$ignore_daemon) { if (DB_TYPE == "pgsql") { $updstart_thresh_qpart = "(ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < NOW() - INTERVAL '120 seconds')"; } else { $updstart_thresh_qpart = "(ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < DATE_SUB(NOW(), INTERVAL 120 SECOND))"; } $result = db_query($link, "SELECT id,update_interval,auth_login,\n\t\t\t\tauth_pass,cache_images,update_method,last_updated\n\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}' AND {$updstart_thresh_qpart}"); } else { $result = db_query($link, "SELECT id,update_interval,auth_login,\n\t\t\t\tfeed_url,auth_pass,cache_images,update_method,last_updated,\n\t\t\t\tmark_unread_on_update, owner_uid, update_on_checksum_change,\n\t\t\t\tpubsub_state\n\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}'"); } if (db_num_rows($result) == 0) { if ($debug_enabled) { _debug("update_rss_feed: feed {$feed} NOT FOUND/SKIPPED"); } return false; } $update_method = db_fetch_result($result, 0, "update_method"); $last_updated = db_fetch_result($result, 0, "last_updated"); $owner_uid = db_fetch_result($result, 0, "owner_uid"); $mark_unread_on_update = sql_bool_to_bool(db_fetch_result($result, 0, "mark_unread_on_update")); $update_on_checksum_change = sql_bool_to_bool(db_fetch_result($result, 0, "update_on_checksum_change")); $pubsub_state = db_fetch_result($result, 0, "pubsub_state"); db_query($link, "UPDATE ttrss_feeds SET last_update_started = NOW()\n\t\t\tWHERE id = '{$feed}'"); $auth_login = db_fetch_result($result, 0, "auth_login"); $auth_pass = db_fetch_result($result, 0, "auth_pass"); if ($update_method == 0) { $update_method = DEFAULT_UPDATE_METHOD + 1; } // 1 - Magpie // 2 - SimplePie // 3 - Twitter OAuth if ($update_method == 2) { $use_simplepie = true; } else { $use_simplepie = false; } if ($debug_enabled) { _debug("update method: {$update_method} (feed setting: {$update_method}) (use simplepie: {$use_simplepie})\n"); } if ($update_method == 1) { $auth_login = urlencode($auth_login); $auth_pass = urlencode($auth_pass); } $cache_images = sql_bool_to_bool(db_fetch_result($result, 0, "cache_images")); $fetch_url = db_fetch_result($result, 0, "feed_url"); $feed = db_escape_string($feed); if ($auth_login && $auth_pass) { $url_parts = array(); preg_match("/(^[^:]*):\\/\\/(.*)/", $fetch_url, $url_parts); if ($url_parts[1] && $url_parts[2]) { $fetch_url = $url_parts[1] . "://{$auth_login}:{$auth_pass}@" . $url_parts[2]; } } if ($override_url) { $fetch_url = $override_url; } if ($debug_enabled) { _debug("update_rss_feed: fetching [{$fetch_url}]..."); } // Ignore cache if new feed or manual update. $cache_age = is_null($last_updated) || $last_updated == '1970-01-01 00:00:00' ? -1 : get_feed_update_interval($link, $feed) * 60; if ($update_method == 3) { $rss = fetch_twitter_rss($link, $fetch_url, $owner_uid); } else { if ($update_method == 1) { define('MAGPIE_CACHE_AGE', $cache_age); define('MAGPIE_CACHE_ON', !$no_cache); define('MAGPIE_FETCH_TIME_OUT', 60); define('MAGPIE_CACHE_DIR', CACHE_DIR . "/magpie"); $rss = @fetch_rss($fetch_url); } else { $simplepie_cache_dir = CACHE_DIR . "/simplepie"; if (!is_dir($simplepie_cache_dir)) { mkdir($simplepie_cache_dir); } $rss = new SimplePie(); $rss->set_useragent(SELF_USER_AGENT); # $rss->set_timeout(10); $rss->set_feed_url($fetch_url); $rss->set_output_encoding('UTF-8'); //$rss->force_feed(true); if ($debug_enabled) { _debug("feed update interval (sec): " . get_feed_update_interval($link, $feed) * 60); } $rss->enable_cache(!$no_cache); if (!$no_cache) { $rss->set_cache_location($simplepie_cache_dir); $rss->set_cache_duration($cache_age); } $rss->init(); } } // print_r($rss); if ($debug_enabled) { _debug("update_rss_feed: fetch done, parsing..."); } $feed = db_escape_string($feed); if ($update_method == 2) { $fetch_ok = !$rss->error(); } else { $fetch_ok = !!$rss; } if ($fetch_ok) { if ($debug_enabled) { _debug("update_rss_feed: processing feed data..."); } // db_query($link, "BEGIN"); if (DB_TYPE == "pgsql") { $favicon_interval_qpart = "favicon_last_checked < NOW() - INTERVAL '12 hour'"; } else { $favicon_interval_qpart = "favicon_last_checked < DATE_SUB(NOW(), INTERVAL 12 HOUR)"; } $result = db_query($link, "SELECT title,icon_url,site_url,owner_uid,\n\t\t\t\t(favicon_last_checked IS NULL OR {$favicon_interval_qpart}) AS\n\t\t\t\t\t\tfavicon_needs_check\n\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}'"); $registered_title = db_fetch_result($result, 0, "title"); $orig_icon_url = db_fetch_result($result, 0, "icon_url"); $orig_site_url = db_fetch_result($result, 0, "site_url"); $favicon_needs_check = sql_bool_to_bool(db_fetch_result($result, 0, "favicon_needs_check")); $owner_uid = db_fetch_result($result, 0, "owner_uid"); if ($use_simplepie) { $site_url = db_escape_string(trim($rss->get_link())); } else { $site_url = db_escape_string(trim($rss->channel["link"])); } // weird, weird Magpie if (!$use_simplepie) { if (!$site_url) { $site_url = db_escape_string($rss->channel["link_"]); } } $site_url = rewrite_relative_url($fetch_url, $site_url); $site_url = substr($site_url, 0, 250); if ($debug_enabled) { _debug("update_rss_feed: checking favicon..."); } if ($favicon_needs_check) { check_feed_favicon($site_url, $feed, $link); db_query($link, "UPDATE ttrss_feeds SET favicon_last_checked = NOW()\n\t\t\t\t\tWHERE id = '{$feed}'"); } if (!$registered_title || $registered_title == "[Unknown]") { if ($use_simplepie) { $feed_title = db_escape_string($rss->get_title()); } else { $feed_title = db_escape_string($rss->channel["title"]); } if ($debug_enabled) { _debug("update_rss_feed: registering title: {$feed_title}"); } db_query($link, "UPDATE ttrss_feeds SET\n\t\t\t\t\ttitle = '{$feed_title}' WHERE id = '{$feed}'"); } if ($site_url && $orig_site_url != $site_url) { db_query($link, "UPDATE ttrss_feeds SET\n\t\t\t\t\tsite_url = '{$site_url}' WHERE id = '{$feed}'"); } // print "I: " . $rss->channel["image"]["url"]; if (!$use_simplepie) { $icon_url = db_escape_string(trim($rss->image["url"])); } else { $icon_url = db_escape_string(trim($rss->get_image_url())); } $icon_url = rewrite_relative_url($fetch_url, $icon_url); $icon_url = substr($icon_url, 0, 250); if ($icon_url && $orig_icon_url != $icon_url) { db_query($link, "UPDATE ttrss_feeds SET icon_url = '{$icon_url}' WHERE id = '{$feed}'"); } if ($debug_enabled) { _debug("update_rss_feed: loading filters..."); } $filters = load_filters($link, $feed, $owner_uid); // if ($debug_enabled) { // print_r($filters); // } if ($use_simplepie) { $iterator = $rss->get_items(); } else { $iterator = $rss->items; if (!$iterator || !is_array($iterator)) { $iterator = $rss->entries; } if (!$iterator || !is_array($iterator)) { $iterator = $rss; } } if (!is_array($iterator)) { /* db_query($link, "UPDATE ttrss_feeds SET last_error = 'Parse error: can\'t find any articles.' WHERE id = '$feed'"); */ // clear any errors and mark feed as updated if fetched okay // even if it's blank if ($debug_enabled) { _debug("update_rss_feed: entry iterator is not an array, no articles?"); } db_query($link, "UPDATE ttrss_feeds\n\t\t\t\t\tSET last_updated = NOW(), last_error = '' WHERE id = '{$feed}'"); return; // no articles } if ($pubsub_state != 2 && PUBSUBHUBBUB_ENABLED) { if ($debug_enabled) { _debug("update_rss_feed: checking for PUSH hub..."); } $feed_hub_url = false; if ($use_simplepie) { $links = $rss->get_links('hub'); if ($links && is_array($links)) { foreach ($links as $l) { $feed_hub_url = $l; break; } } } else { $atom = $rss->channel['atom']; if ($atom) { if ($atom['link@rel'] == 'hub') { $feed_hub_url = $atom['link@href']; } if (!$feed_hub_url && $atom['link#'] > 1) { for ($i = 2; $i <= $atom['link#']; $i++) { if ($atom["link#{$i}@rel"] == 'hub') { $feed_hub_url = $atom["link#{$i}@href"]; break; } } } } else { $feed_hub_url = $rss->channel['link_hub']; } } if ($debug_enabled) { _debug("update_rss_feed: feed hub url: {$feed_hub_url}"); } if ($feed_hub_url && function_exists('curl_init') && !ini_get("open_basedir")) { require_once 'lib/pubsubhubbub/subscriber.php'; $callback_url = get_self_url_prefix() . "/public.php?op=pubsub&id={$feed}"; $s = new Subscriber($feed_hub_url, $callback_url); $rc = $s->subscribe($fetch_url); if ($debug_enabled) { _debug("update_rss_feed: feed hub url found, subscribe request sent."); } db_query($link, "UPDATE ttrss_feeds SET pubsub_state = 1\n\t\t\t\t\t\tWHERE id = '{$feed}'"); } } if ($debug_enabled) { _debug("update_rss_feed: processing articles..."); } foreach ($iterator as $item) { if ($_REQUEST['xdebug'] == 2) { print_r($item); } if ($use_simplepie) { $entry_guid = $item->get_id(); if (!$entry_guid) { $entry_guid = $item->get_link(); } if (!$entry_guid) { $entry_guid = make_guid_from_title($item->get_title()); } } else { $entry_guid = $item["id"]; if (!$entry_guid) { $entry_guid = $item["guid"]; } if (!$entry_guid) { $entry_guid = $item["about"]; } if (!$entry_guid) { $entry_guid = $item["link"]; } if (!$entry_guid) { $entry_guid = make_guid_from_title($item["title"]); } } if ($debug_enabled) { _debug("update_rss_feed: guid {$entry_guid}"); } if (!$entry_guid) { continue; } $entry_timestamp = ""; if ($use_simplepie) { $entry_timestamp = strtotime($item->get_date()); } else { $rss_2_date = $item['pubdate']; $rss_1_date = $item['dc']['date']; $atom_date = $item['issued']; if (!$atom_date) { $atom_date = $item['updated']; } if ($atom_date != "") { $entry_timestamp = parse_w3cdtf($atom_date); } if ($rss_1_date != "") { $entry_timestamp = parse_w3cdtf($rss_1_date); } if ($rss_2_date != "") { $entry_timestamp = strtotime($rss_2_date); } } if ($entry_timestamp == "" || $entry_timestamp == -1 || !$entry_timestamp) { $entry_timestamp = time(); $no_orig_date = 'true'; } else { $no_orig_date = 'false'; } $entry_timestamp_fmt = strftime("%Y/%m/%d %H:%M:%S", $entry_timestamp); if ($debug_enabled) { _debug("update_rss_feed: date {$entry_timestamp} [{$entry_timestamp_fmt}]"); } if ($use_simplepie) { $entry_title = $item->get_title(); } else { $entry_title = trim(strip_tags($item["title"])); } if ($use_simplepie) { $entry_link = $item->get_link(); } else { // strange Magpie workaround $entry_link = $item["link_"]; if (!$entry_link) { $entry_link = $item["link"]; } } $entry_link = rewrite_relative_url($site_url, $entry_link); if ($debug_enabled) { _debug("update_rss_feed: title {$entry_title}"); _debug("update_rss_feed: link {$entry_link}"); } if (!$entry_title) { $entry_title = date("Y-m-d H:i:s", $entry_timestamp); } $entry_link = strip_tags($entry_link); if ($use_simplepie) { $entry_content = $item->get_content(); if (!$entry_content) { $entry_content = $item->get_description(); } } else { $entry_content = $item["content:escaped"]; if (!$entry_content) { $entry_content = $item["content:encoded"]; } if (!$entry_content && is_array($entry_content)) { $entry_content = $item["content"]["encoded"]; } if (!$entry_content) { $entry_content = $item["content"]; } if (is_array($entry_content)) { $entry_content = $entry_content[0]; } // Magpie bugs are getting ridiculous if (trim($entry_content) == "Array") { $entry_content = false; } if (!$entry_content) { $entry_content = $item["atom_content"]; } if (!$entry_content) { $entry_content = $item["summary"]; } if (!$entry_content || strlen($entry_content) < strlen($item["description"])) { $entry_content = $item["description"]; } // WTF if (is_array($entry_content)) { $entry_content = $entry_content["encoded"]; if (!$entry_content) { $entry_content = $entry_content["escaped"]; } } } if ($cache_images && is_writable(CACHE_DIR . '/images')) { $entry_content = cache_images($entry_content, $site_url, $debug_enabled); } if ($_REQUEST["xdebug"] == 2) { print "update_rss_feed: content: "; print $entry_content; print "\n"; } $entry_content_unescaped = $entry_content; if ($use_simplepie) { $entry_comments = strip_tags($item->data["comments"]); if ($item->get_author()) { $entry_author_item = $item->get_author(); $entry_author = $entry_author_item->get_name(); if (!$entry_author) { $entry_author = $entry_author_item->get_email(); } $entry_author = db_escape_string($entry_author); } } else { $entry_comments = strip_tags($item["comments"]); $entry_author = db_escape_string(strip_tags($item['dc']['creator'])); if ($item['author']) { if (is_array($item['author'])) { if (!$entry_author) { $entry_author = db_escape_string(strip_tags($item['author']['name'])); } if (!$entry_author) { $entry_author = db_escape_string(strip_tags($item['author']['email'])); } } if (!$entry_author) { $entry_author = db_escape_string(strip_tags($item['author'])); } } } if (preg_match('/^[\\t\\n\\r ]*$/', $entry_author)) { $entry_author = ''; } $entry_guid = db_escape_string(strip_tags($entry_guid)); $entry_guid = mb_substr($entry_guid, 0, 250); $result = db_query($link, "SELECT id FROM\tttrss_entries\n\t\t\t\t\tWHERE guid = '{$entry_guid}'"); $entry_content = db_escape_string($entry_content, false); $content_hash = "SHA1:" . sha1(strip_tags($entry_content)); $entry_title = db_escape_string($entry_title); $entry_link = db_escape_string($entry_link); $entry_comments = mb_substr(db_escape_string($entry_comments), 0, 250); $entry_author = mb_substr($entry_author, 0, 250); if ($use_simplepie) { $num_comments = 0; #FIXME# } else { $num_comments = db_escape_string($item["slash"]["comments"]); } if (!$num_comments) { $num_comments = 0; } if ($debug_enabled) { _debug("update_rss_feed: looking for tags [1]..."); } // parse <category> entries into tags $additional_tags = array(); if ($use_simplepie) { $additional_tags_src = $item->get_categories(); if (is_array($additional_tags_src)) { foreach ($additional_tags_src as $tobj) { array_push($additional_tags, $tobj->get_term()); } } if ($debug_enabled) { _debug("update_rss_feed: category tags:"); print_r($additional_tags); } } else { $t_ctr = $item['category#']; if ($t_ctr == 0) { $additional_tags = array(); } else { if ($t_ctr > 0) { $additional_tags = array($item['category']); if ($item['category@term']) { array_push($additional_tags, $item['category@term']); } for ($i = 0; $i <= $t_ctr; $i++) { if ($item["category#{$i}"]) { array_push($additional_tags, $item["category#{$i}"]); } if ($item["category#{$i}@term"]) { array_push($additional_tags, $item["category#{$i}@term"]); } } } } // parse <dc:subject> elements $t_ctr = $item['dc']['subject#']; if ($t_ctr > 0) { array_push($additional_tags, $item['dc']['subject']); for ($i = 0; $i <= $t_ctr; $i++) { if ($item['dc']["subject#{$i}"]) { array_push($additional_tags, $item['dc']["subject#{$i}"]); } } } } if ($debug_enabled) { _debug("update_rss_feed: looking for tags [2]..."); } /* taaaags */ // <a href="..." rel="tag">Xorg</a>, // $entry_tags = null; preg_match_all("/<a.*?rel=['\"]tag['\"].*?\\>([^<]+)<\\/a>/i", $entry_content_unescaped, $entry_tags); $entry_tags = $entry_tags[1]; $entry_tags = array_merge($entry_tags, $additional_tags); $entry_tags = array_unique($entry_tags); for ($i = 0; $i < count($entry_tags); $i++) { $entry_tags[$i] = mb_strtolower($entry_tags[$i], 'utf-8'); } if ($debug_enabled) { //_debug("update_rss_feed: unfiltered tags found:"); //print_r($entry_tags); } # sanitize content $entry_content = sanitize_article_content($entry_content); $entry_title = sanitize_article_content($entry_title); if ($debug_enabled) { _debug("update_rss_feed: done collecting data [TITLE:{$entry_title}]"); } db_query($link, "BEGIN"); if (db_num_rows($result) == 0) { if ($debug_enabled) { _debug("update_rss_feed: base guid not found"); } // base post entry does not exist, create it $result = db_query($link, "INSERT INTO ttrss_entries\n\t\t\t\t\t\t\t(title,\n\t\t\t\t\t\t\tguid,\n\t\t\t\t\t\t\tlink,\n\t\t\t\t\t\t\tupdated,\n\t\t\t\t\t\t\tcontent,\n\t\t\t\t\t\t\tcontent_hash,\n\t\t\t\t\t\t\tno_orig_date,\n\t\t\t\t\t\t\tdate_updated,\n\t\t\t\t\t\t\tdate_entered,\n\t\t\t\t\t\t\tcomments,\n\t\t\t\t\t\t\tnum_comments,\n\t\t\t\t\t\t\tauthor)\n\t\t\t\t\t\tVALUES\n\t\t\t\t\t\t\t('{$entry_title}',\n\t\t\t\t\t\t\t'{$entry_guid}',\n\t\t\t\t\t\t\t'{$entry_link}',\n\t\t\t\t\t\t\t'{$entry_timestamp_fmt}',\n\t\t\t\t\t\t\t'{$entry_content}',\n\t\t\t\t\t\t\t'{$content_hash}',\n\t\t\t\t\t\t\t{$no_orig_date},\n\t\t\t\t\t\t\tNOW(),\n\t\t\t\t\t\t\tNOW(),\n\t\t\t\t\t\t\t'{$entry_comments}',\n\t\t\t\t\t\t\t'{$num_comments}',\n\t\t\t\t\t\t\t'{$entry_author}')"); } else { // we keep encountering the entry in feeds, so we need to // update date_updated column so that we don't get horrible // dupes when the entry gets purged and reinserted again e.g. // in the case of SLOW SLOW OMG SLOW updating feeds $base_entry_id = db_fetch_result($result, 0, "id"); db_query($link, "UPDATE ttrss_entries SET date_updated = NOW()\n\t\t\t\t\t\tWHERE id = '{$base_entry_id}'"); } // now it should exist, if not - bad luck then $result = db_query($link, "SELECT\n\t\t\t\t\t\tid,content_hash,no_orig_date,title,\n\t\t\t\t\t\t" . SUBSTRING_FOR_DATE . "(date_updated,1,19) as date_updated,\n\t\t\t\t\t\t" . SUBSTRING_FOR_DATE . "(updated,1,19) as updated,\n\t\t\t\t\t\tnum_comments\n\t\t\t\t\tFROM\n\t\t\t\t\t\tttrss_entries\n\t\t\t\t\tWHERE guid = '{$entry_guid}'"); $entry_ref_id = 0; $entry_int_id = 0; if (db_num_rows($result) == 1) { if ($debug_enabled) { _debug("update_rss_feed: base guid found, checking for user record"); } // this will be used below in update handler $orig_content_hash = db_fetch_result($result, 0, "content_hash"); $orig_title = db_fetch_result($result, 0, "title"); $orig_num_comments = db_fetch_result($result, 0, "num_comments"); $orig_date_updated = strtotime(db_fetch_result($result, 0, "date_updated")); $ref_id = db_fetch_result($result, 0, "id"); $entry_ref_id = $ref_id; // check for user post link to main table // do we allow duplicate posts with same GUID in different feeds? if (get_pref($link, "ALLOW_DUPLICATE_POSTS", $owner_uid, false)) { $dupcheck_qpart = "AND (feed_id = '{$feed}' OR feed_id IS NULL)"; } else { $dupcheck_qpart = ""; } /* Collect article tags here so we could filter by them: */ $article_filters = get_article_filters($filters, $entry_title, $entry_content, $entry_link, $entry_timestamp, $entry_author, $entry_tags); if ($debug_enabled) { _debug("update_rss_feed: article filters: "); if (count($article_filters) != 0) { print_r($article_filters); } } if (find_article_filter($article_filters, "filter")) { db_query($link, "COMMIT"); // close transaction in progress continue; } $score = calculate_article_score($article_filters); if ($debug_enabled) { _debug("update_rss_feed: initial score: {$score}"); } $query = "SELECT ref_id, int_id FROM ttrss_user_entries WHERE\n\t\t\t\t\t\t\tref_id = '{$ref_id}' AND owner_uid = '{$owner_uid}'\n\t\t\t\t\t\t\t{$dupcheck_qpart}"; // if ($_REQUEST["xdebug"]) print "$query\n"; $result = db_query($link, $query); // okay it doesn't exist - create user entry if (db_num_rows($result) == 0) { if ($debug_enabled) { _debug("update_rss_feed: user record not found, creating..."); } if ($score >= -500 && !find_article_filter($article_filters, 'catchup')) { $unread = 'true'; $last_read_qpart = 'NULL'; } else { $unread = 'false'; $last_read_qpart = 'NOW()'; } if (find_article_filter($article_filters, 'mark') || $score > 1000) { $marked = 'true'; } else { $marked = 'false'; } if (find_article_filter($article_filters, 'publish')) { $published = 'true'; } else { $published = 'false'; } // N-grams if (DB_TYPE == "pgsql" and defined('_NGRAM_TITLE_DUPLICATE_THRESHOLD')) { $result = db_query($link, "SELECT COUNT(*) AS similar FROM\n\t\t\t\t\t\t\t\t\tttrss_entries,ttrss_user_entries\n\t\t\t\t\t\t\t\tWHERE ref_id = id AND updated >= NOW() - INTERVAL '7 day'\n\t\t\t\t\t\t\t\t\tAND similarity(title, '{$entry_title}') >= " . _NGRAM_TITLE_DUPLICATE_THRESHOLD . "\n\t\t\t\t\t\t\t\t\tAND owner_uid = {$owner_uid}"); $ngram_similar = db_fetch_result($result, 0, "similar"); if ($debug_enabled) { _debug("update_rss_feed: N-gram similar results: {$ngram_similar}"); } if ($ngram_similar > 0) { $unread = 'false'; } } $result = db_query($link, "INSERT INTO ttrss_user_entries\n\t\t\t\t\t\t\t\t(ref_id, owner_uid, feed_id, unread, last_read, marked,\n\t\t\t\t\t\t\t\t\tpublished, score, tag_cache, label_cache, uuid)\n\t\t\t\t\t\t\tVALUES ('{$ref_id}', '{$owner_uid}', '{$feed}', {$unread},\n\t\t\t\t\t\t\t\t{$last_read_qpart}, {$marked}, {$published}, '{$score}', '', '', '')"); if (PUBSUBHUBBUB_HUB && $published == 'true') { $rss_link = get_self_url_prefix() . "/public.php?op=rss&id=-2&key=" . get_feed_access_key($link, -2, false, $owner_uid); $p = new Publisher(PUBSUBHUBBUB_HUB); $pubsub_result = $p->publish_update($rss_link); } $result = db_query($link, "SELECT int_id FROM ttrss_user_entries WHERE\n\t\t\t\t\t\t\t\tref_id = '{$ref_id}' AND owner_uid = '{$owner_uid}' AND\n\t\t\t\t\t\t\t\tfeed_id = '{$feed}' LIMIT 1"); if (db_num_rows($result) == 1) { $entry_int_id = db_fetch_result($result, 0, "int_id"); } } else { if ($debug_enabled) { _debug("update_rss_feed: user record FOUND"); } $entry_ref_id = db_fetch_result($result, 0, "ref_id"); $entry_int_id = db_fetch_result($result, 0, "int_id"); } if ($debug_enabled) { _debug("update_rss_feed: RID: {$entry_ref_id}, IID: {$entry_int_id}"); } $post_needs_update = false; $update_insignificant = false; if ($orig_num_comments != $num_comments) { $post_needs_update = true; $update_insignificant = true; } if ($content_hash != $orig_content_hash) { $post_needs_update = true; $update_insignificant = false; } if (db_escape_string($orig_title) != $entry_title) { $post_needs_update = true; $update_insignificant = false; } // if post needs update, update it and mark all user entries // linking to this post as updated if ($post_needs_update) { if (defined('DAEMON_EXTENDED_DEBUG')) { _debug("update_rss_feed: post {$entry_guid} needs update..."); } // print "<!-- post $orig_title needs update : $post_needs_update -->"; db_query($link, "UPDATE ttrss_entries\n\t\t\t\t\t\t\tSET title = '{$entry_title}', content = '{$entry_content}',\n\t\t\t\t\t\t\t\tcontent_hash = '{$content_hash}',\n\t\t\t\t\t\t\t\tupdated = '{$entry_timestamp_fmt}',\n\t\t\t\t\t\t\t\tnum_comments = '{$num_comments}'\n\t\t\t\t\t\t\tWHERE id = '{$ref_id}'"); if (!$update_insignificant) { if ($mark_unread_on_update) { db_query($link, "UPDATE ttrss_user_entries\n\t\t\t\t\t\t\t\t\tSET last_read = null, unread = true WHERE ref_id = '{$ref_id}'"); } else { if ($update_on_checksum_change) { db_query($link, "UPDATE ttrss_user_entries\n\t\t\t\t\t\t\t\t\tSET last_read = null WHERE ref_id = '{$ref_id}'\n\t\t\t\t\t\t\t\t\t\tAND unread = false"); } } } } } db_query($link, "COMMIT"); if ($debug_enabled) { _debug("update_rss_feed: assigning labels..."); } assign_article_to_labels($link, $entry_ref_id, $article_filters, $owner_uid); if ($debug_enabled) { _debug("update_rss_feed: looking for enclosures..."); } // enclosures $enclosures = array(); if ($use_simplepie) { $encs = $item->get_enclosures(); if (is_array($encs)) { foreach ($encs as $e) { $e_item = array($e->link, $e->type, $e->length); array_push($enclosures, $e_item); } } } else { // <enclosure> $e_ctr = $item['enclosure#']; if ($e_ctr > 0) { $e_item = array($item['enclosure@url'], $item['enclosure@type'], $item['enclosure@length']); array_push($enclosures, $e_item); for ($i = 0; $i <= $e_ctr; $i++) { if ($item["enclosure#{$i}@url"]) { $e_item = array($item["enclosure#{$i}@url"], $item["enclosure#{$i}@type"], $item["enclosure#{$i}@length"]); array_push($enclosures, $e_item); } } } // <media:content> // can there be many of those? yes -fox $m_ctr = $item['media']['content#']; if ($m_ctr > 0) { $e_item = array($item['media']['content@url'], $item['media']['content@medium'], $item['media']['content@length']); array_push($enclosures, $e_item); for ($i = 0; $i <= $m_ctr; $i++) { if ($item["media"]["content#{$i}@url"]) { $e_item = array($item["media"]["content#{$i}@url"], $item["media"]["content#{$i}@medium"], $item["media"]["content#{$i}@length"]); array_push($enclosures, $e_item); } } } } if ($debug_enabled) { _debug("update_rss_feed: article enclosures:"); print_r($enclosures); } db_query($link, "BEGIN"); foreach ($enclosures as $enc) { $enc_url = db_escape_string($enc[0]); $enc_type = db_escape_string($enc[1]); $enc_dur = db_escape_string($enc[2]); $result = db_query($link, "SELECT id FROM ttrss_enclosures\n\t\t\t\t\t\tWHERE content_url = '{$enc_url}' AND post_id = '{$entry_ref_id}'"); if (db_num_rows($result) == 0) { db_query($link, "INSERT INTO ttrss_enclosures\n\t\t\t\t\t\t\t(content_url, content_type, title, duration, post_id) VALUES\n\t\t\t\t\t\t\t('{$enc_url}', '{$enc_type}', '', '{$enc_dur}', '{$entry_ref_id}')"); } } db_query($link, "COMMIT"); // check for manual tags (we have to do it here since they're loaded from filters) foreach ($article_filters as $f) { if ($f["type"] == "tag") { $manual_tags = trim_array(explode(",", $f["param"])); foreach ($manual_tags as $tag) { if (tag_is_valid($tag)) { array_push($entry_tags, $tag); } } } } // Skip boring tags $boring_tags = trim_array(explode(",", mb_strtolower(get_pref($link, 'BLACKLISTED_TAGS', $owner_uid, ''), 'utf-8'))); $filtered_tags = array(); $tags_to_cache = array(); if ($entry_tags && is_array($entry_tags)) { foreach ($entry_tags as $tag) { if (array_search($tag, $boring_tags) === false) { array_push($filtered_tags, $tag); } } } $filtered_tags = array_unique($filtered_tags); if ($debug_enabled) { _debug("update_rss_feed: filtered article tags:"); print_r($filtered_tags); } // Save article tags in the database if (count($filtered_tags) > 0) { db_query($link, "BEGIN"); foreach ($filtered_tags as $tag) { $tag = sanitize_tag($tag); $tag = db_escape_string($tag); if (!tag_is_valid($tag)) { continue; } $result = db_query($link, "SELECT id FROM ttrss_tags\n\t\t\t\t\t\t\tWHERE tag_name = '{$tag}' AND post_int_id = '{$entry_int_id}' AND\n\t\t\t\t\t\t\towner_uid = '{$owner_uid}' LIMIT 1"); if ($result && db_num_rows($result) == 0) { db_query($link, "INSERT INTO ttrss_tags\n\t\t\t\t\t\t\t\t\t(owner_uid,tag_name,post_int_id)\n\t\t\t\t\t\t\t\t\tVALUES ('{$owner_uid}','{$tag}', '{$entry_int_id}')"); } array_push($tags_to_cache, $tag); } /* update the cache */ $tags_to_cache = array_unique($tags_to_cache); $tags_str = db_escape_string(join(",", $tags_to_cache)); db_query($link, "UPDATE ttrss_user_entries\n\t\t\t\t\t\tSET tag_cache = '{$tags_str}' WHERE ref_id = '{$entry_ref_id}'\n\t\t\t\t\t\tAND owner_uid = {$owner_uid}"); db_query($link, "COMMIT"); } if ($debug_enabled) { _debug("update_rss_feed: article processed"); } } if (!$last_updated) { if ($debug_enabled) { _debug("update_rss_feed: new feed, catching it up..."); } catchup_feed($link, $feed, false, $owner_uid); } if ($debug_enabled) { _debug("purging feed..."); } purge_feed($link, $feed, 0, $debug_enabled); db_query($link, "UPDATE ttrss_feeds\n\t\t\t\tSET last_updated = NOW(), last_error = '' WHERE id = '{$feed}'"); // db_query($link, "COMMIT"); } else { if ($use_simplepie) { $error_msg = mb_substr($rss->error(), 0, 250); } else { $error_msg = mb_substr(magpie_error(), 0, 250); } if ($debug_enabled) { _debug("update_rss_feed: error fetching feed: {$error_msg}"); } $error_msg = db_escape_string($error_msg); db_query($link, "UPDATE ttrss_feeds SET last_error = '{$error_msg}',\n\t\t\t\t\tlast_updated = NOW() WHERE id = '{$feed}'"); } if ($use_simplepie) { unset($rss); } if ($debug_enabled) { _debug("update_rss_feed: done"); } }
/** * Try to read the date and return as timestamp * * @param string $datestr * @return int the date */ function _parse_date($datestr) { //$datestr = preg_replace("/^\s*([0-9]{1,2})[\/\. -]+([0-9]{1,2})[\/\. -]+([0-9]{2,4})/", "\\2/\\1/\\3", $datestr); // $datestr = str_replace('/', '-', $datestr); if (is_numeric($datestr)) { return $datestr; } $date = strtotime($datestr); if ($date == -1) { $date = parse_w3cdtf($datestr); } if ($date == -1 || $date == "") { $date = time(); } return $date; }
$dccreator = $row['dccreator']; $dcdate = $row['dcdate']; $dcsubject = $row['dcsubject']; print '<div class="item">'; print '<div class="header">'; print "<a class=\"headline\" href=\"{$item_link}\">{$item_title}</a> "; print "<a class=\"feed\" href=\"{$feed_link}\" title=\"{$feed_description}\">{$feed_title}</a>"; print '<span class="meta">'; if ($dccreator) { print "by {$dccreator} "; } if ($dcsubject) { print "on {$dcsubject} "; } if ($dcdate) { $dcdate = date("F j, Y, g:i a", parse_w3cdtf($dcdate) + $asec - FOF_TIME_OFFSET * 60 * 60); print "at {$dcdate} "; } print "(cached at {$timestamp})</span>"; if (!$noedit) { echo ' <span class="controls">'; print "<a href=\"javascript:flag_upto('c{$item_id}')\">flag all up to this item</a> "; print "<input type=\"checkbox\" name=\"c{$item_id}\" value=\"checked\" />"; echo '</span>'; } print "<div class=\"clearer\"></div><br/></div><div class=\"body\">{$item_content}</div></div>"; } if (!$items) { echo "No items found."; } if (!$noedit) {
//gestion de la date de publication, selon le flux, elle se trouve parsee ? des endroits differents if ($item['pubdate']) { $aso_page['datestamp'] = strtotime($item['pubdate']); } elseif ($item['dc']['date']) { //en php5 on peut convertir les formats de dates exotiques plus facilement if (PHP_VERSION >= 5) { $aso_page['datestamp'] = strtotime($item['dc']['date']); } else { $aso_page['datestamp'] = parse_w3cdtf($item['dc']['date']); } } elseif ($item['issued']) { //en php5 on peut convertir les formats de dates exotiques plus facilement if (PHP_VERSION >= 5) { $aso_page['datestamp'] = strtotime($item['issued']); } else { $aso_page['datestamp'] = parse_w3cdtf($item['issued']); } } else { $aso_page['datestamp'] = time(); } if ($formatdate != '') { switch ($formatdate) { case 'jm': $aso_page['date'] = strftime('%d.%m', $aso_page['datestamp']); break; case 'jma': $aso_page['date'] = strftime('%d.%m.%Y', $aso_page['datestamp']); break; case 'jmh': $aso_page['date'] = strftime('%d.%m %H:%M', $aso_page['datestamp']); break;
function get_feed_item_date($item) { //Is there an Atom date? If so, parse it. if (isset($item['issued']) && ($atom_date = $item['issued'])) { $date = parse_w3cdtf($atom_date); } elseif (isset($item['pubdate']) && ($rss_2_date = $item['pubdate'])) { $date = strtotime($rss_2_date); } elseif (isset($item['dc']['date']) && ($rss_1_date = $item['dc']['date'])) { $date = parse_w3cdtf($rss_1_date); } else { $date = null; } //Return a UNIX timestamp. if ($date) { return $date; } else { return 0; } }
function update($id) { $kses_allowed = getConfig('rss.input.allowed'); //getAllowedTags(); $updatedIds = array(); $sql = "select id, url, title, mode from " . getTable("channels"); if ($id != "" && is_numeric($id)) { $sql .= " where id={$id}"; $sql .= " and not(mode & " . RSS_MODE_DELETED_STATE . ") "; } else { $sql .= " where not(mode & " . RSS_MODE_DELETED_STATE . ") "; } if (getConfig('rss.config.absoluteordering')) { $sql .= " order by parent, position"; } else { $sql .= " order by parent, title"; } $res = rss_query($sql); while (list($cid, $url, $title, $mode) = rss_fetch_row($res)) { // suppress warnings because Magpie is rather noisy $old_level = error_reporting(E_ERROR); $rss = fetch_rss($url); //reset error_reporting($old_level); if (!$rss && $id != "" && is_numeric($id)) { return array(magpie_error(), array()); } elseif (!$rss || !($rss->rss_origin & MAGPIE_FEED_ORIGIN_HTTP_200)) { continue; // no need to do anything if we do not get a 200 OK from the feed } // base URL for items in this feed. if (array_key_exists('link', $rss->channel)) { $baseUrl = $rss->channel['link']; } else { $baseUrl = $url; // The feed is invalid } // Keep track of guids we've handled, because some feeds (hello, // Technorati!) have this insane habit of serving the same item // twice in the same feed. $guids = array(); // Allow updates in this feed? $allowUpdates = getProperty($cid, 'rss.input.allowupdates'); if ($allowUpdates === null) { $allowUpdates = getConfig('rss.input.allowupdates'); } $itemIdsInFeed = array(); // This variable will store the item id's of the elements in the feed foreach ($rss->items as $item) { $item = rss_plugin_hook('rss.plugins.rssitem', $item); // a plugin might delete this item if (!isset($item)) { continue; } // item title: strip out html tags $title = array_key_exists('title', $item) ? strip_tags($item['title']) : ""; //$title = str_replace('& ', '& ', $title); $description = ""; // item content, if any if (array_key_exists('content', $item) && is_array($item['content']) && array_key_exists('encoded', $item['content'])) { $description = $item['content']['encoded']; } elseif (array_key_exists('description', $item)) { $description = $item['description']; } elseif (array_key_exists('atom_content', $item)) { $description = $item['atom_content']; } elseif (array_key_exists('summary', $item)) { $description = $item['summary']; } else { $description = ""; } $md5sum = ""; $guid = ""; if (array_key_exists('guid', $item) && $item['guid'] != "") { $guid = $item['guid']; } elseif (array_key_exists('id', $item) && $item['id'] != "") { $guid = $item['id']; } $guid = trim($guid); $guid = rss_real_escape_string($guid); // skip this one if it's an in-feed-dupe if ($guid && isset($guids[$guid])) { continue; } elseif ($guid) { $guids[$guid] = true; } if ($description != "") { $md5sum = md5($description); $description = kses($description, $kses_allowed); // strip out tags if ($baseUrl != "") { $description = relative_to_absolute($description, $baseUrl); } } // Now let plugins modify the description $description = rss_plugin_hook('rss.plugins.import.description', $description); // link if (array_key_exists('link', $item) && $item['link'] != "") { $url = $item['link']; } elseif (array_key_exists('guid', $item) && $item['guid'] != "") { $url = $item['guid']; } elseif (array_key_exists('link_', $item) && $item['link_'] != "") { $url = $item['link_']; } else { // fall back to something basic $url = md5($title); } // make sure the url is properly escaped $url = htmlentities($url, ENT_QUOTES); $url = rss_real_escape_string($url); // author if (array_key_exists('dc', $item) && array_key_exists('creator', $item['dc'])) { // RSS 1.0 $author = $item['dc']['creator']; } else { if (array_key_exists('author_name', $item)) { // Atom 0.3 $author = $item['author_name']; } else { $author = ""; } } $author = trim(strip_tags($author)); // pubdate $cDate = -1; if (array_key_exists('dc', $item) && array_key_exists('date', $item['dc'])) { // RSS 1.0 $cDate = parse_w3cdtf($item['dc']['date']); } elseif (array_key_exists('pubdate', $item)) { // RSS 2.0 (?) // We use the second param of strtotime here as a workaround // of a PHP bug with strtotime. If the pubdate field doesn't // contain seconds, the strtotime function will use the current // time to fill in seconds in PHP4. This interferes with the // update mechanism of gregarius. See ticket #328 for the full // gory details. Giving a known date as a second param to // strtotime fixes this problem, hence the 0 here. $cDate = strtotime($item['pubdate'], 0); } elseif (array_key_exists('published', $item)) { // atom 1.0 $cDate = parse_iso8601($item['published']); } elseif (array_key_exists('issued', $item)) { //Atom, alternative $cDate = parse_iso8601($item['issued']); } elseif (array_key_exists('updated', $item)) { //Atom, alternative $cDate = parse_iso8601($item['updated']); } elseif (array_key_exists('created', $item)) { // atom 0.3 $cDate = parse_iso8601($item['created']); } // enclosure if (array_key_exists('enclosure@url', $item)) { $enclosure = $item['enclosure@url']; // If the enclosure is an image, append it to the content // but only if it isn't there yet if ($enclosure && array_key_exists('enclosure@type', $item) && preg_match('#image/(png|gif|jpe?g)#', $item['enclosure@type']) && FALSE == strpos($description, $enclosure)) { $description = '<img src="' . $enclosure . '" alt="" />' . $description; $enclosure = ''; } } else { $enclosure = ""; } // drop items with an url exceeding our column length: we couldn't provide a // valid link back anyway. if (strlen($url) >= 255) { continue; } $dbtitle = rss_real_escape_string($title); if (strlen($dbtitle) >= 255) { $dbtitle = substr($dbtitle, 0, 254); } if ($cDate > 0) { $sec = "FROM_UNIXTIME({$cDate})"; } else { $sec = "null"; } // check whether we already have this item if ($guid) { $sql = "select id,unread, md5sum, guid, pubdate from " . getTable("item") . " where cid={$cid} and guid='{$guid}'"; } else { $sql = "select id,unread, md5sum, guid, pubdate from " . getTable("item") . " where cid={$cid} and url='{$url}' and title='{$dbtitle}'" . " and (pubdate is NULL OR pubdate={$sec})"; } $subres = rss_query($sql); list($indb, $state, $dbmd5sum, $dbGuid, $dbPubDate) = rss_fetch_row($subres); if ($indb) { $itemIdsInFeed[] = $indb; if (!($state & RSS_MODE_DELETED_STATE) && $md5sum != $dbmd5sum) { // the md5sums do not match. if ($allowUpdates) { // Are we allowed update items in the db? list($cid, $indb, $description) = rss_plugin_hook('rss.plugins.items.updated', array($cid, $indb, $description)); $sql = "update " . getTable("item") . " set " . " description='" . rss_real_escape_string($description) . "', " . " unread = unread | " . RSS_MODE_UNREAD_STATE . ", md5sum='{$md5sum}'" . " where cid={$cid} and id={$indb}"; rss_query($sql); $updatedIds[] = $indb; continue; } } } else { // $indb = "" . This must be new item then. In you go. list($cid, $dbtitle, $url, $description) = rss_plugin_hook('rss.plugins.items.new', array($cid, $dbtitle, $url, $description)); $sql = "insert into " . getTable("item") . " (cid, added, title, url, enclosure," . " description, author, unread, pubdate, md5sum, guid) " . " values (" . "{$cid}, now(), '{$dbtitle}', " . " '{$url}', '" . rss_real_escape_string($enclosure) . "', '" . rss_real_escape_string($description) . "', '" . rss_real_escape_string($author) . "', " . "{$mode}, {$sec}, '{$md5sum}', '{$guid}')"; rss_query($sql); $newIid = rss_insert_id(); $itemIdsInFeed[] = $newIid; $updatedIds[] = $newIid; rss_plugin_hook('rss.plugins.items.newiid', array($newIid, $item, $cid)); } // end handling of this item } // end handling of all the items in this feed $sql = "update " . getTable("channels") . " set " . " itemsincache = '" . serialize($itemIdsInFeed) . "' where id={$cid}"; rss_query($sql); } // end handling all the feeds we were asked to handle if ($id != "" && is_numeric($id)) { if ($rss) { // when everything went well, return the error code // and numer of new items return array($rss->rss_origin, $updatedIds); } else { return array(-1, array()); } } else { return array(-1, $updatedIds); } }
function normalize() { // if atom populate rss fields and normalize 0.3 and 1.0 feeds if ($this->is_atom()) { // Atom 1.0 elements <=> Atom 0.3 elements (Thanks, o brilliant wordsmiths of the Atom 1.0 standard!) if ($this->feed_version < 1.0) { $this->normalize_element($this->channel, 'tagline', $this->channel, 'subtitle'); $this->normalize_element($this->channel, 'copyright', $this->channel, 'rights'); $this->normalize_element($this->channel, 'modified', $this->channel, 'updated'); } else { $this->normalize_element($this->channel, 'subtitle', $this->channel, 'tagline'); $this->normalize_element($this->channel, 'rights', $this->channel, 'copyright'); $this->normalize_element($this->channel, 'updated', $this->channel, 'modified'); } $this->normalize_element($this->channel, 'author', $this->channel['dc'], 'creator', 'normalize_atom_person'); $this->normalize_element($this->channel, 'contributor', $this->channel['dc'], 'contributor', 'normalize_atom_person'); // Atom elements to RSS elements $this->normalize_element($this->channel, 'subtitle', $this->channel, 'description'); if (isset($this->channel['logo'])) { $this->normalize_element($this->channel, 'logo', $this->image, 'url'); $this->normalize_element($this->channel, 'link', $this->image, 'link'); $this->normalize_element($this->channel, 'title', $this->image, 'title'); } for ($i = 0; $i < count($this->items); $i++) { $item = $this->items[$i]; // Atom 1.0 elements <=> Atom 0.3 elements if ($this->feed_version < 1.0) { $this->normalize_element($item, 'modified', $item, 'updated'); $this->normalize_element($item, 'issued', $item, 'published'); } else { $this->normalize_element($item, 'updated', $item, 'modified'); $this->normalize_element($item, 'published', $item, 'issued'); } // "If an atom:entry element does not contain // atom:author elements, then the atom:author elements // of the contained atom:source element are considered // to apply. In an Atom Feed Document, the atom:author // elements of the containing atom:feed element are // considered to apply to the entry if there are no // atom:author elements in the locations described // above." <http://atompub.org/2005/08/17/draft-ietf-atompub-format-11.html#rfc.section.4.2.1> if (!isset($item["author#"])) { if (isset($item["source_author#"])) { // from aggregation source $source = $item; $author = "source_author"; } elseif (isset($this->channel["author#"])) { // from containing feed $source = $this->channel; $author = "author"; } else { $author = null; } if (!is_null($author)) { $item["author#"] = $source["{$author}#"]; for ($au = 1; $au <= $item["author#"]; $au++) { $id_to = $this->element_id('author', $au); $id_from = $this->element_id($author, $au); $item[$id_to] = $source[$id_from]; foreach (array('name', 'email', 'uri', 'url') as $what) { if (isset($source["{$id_from}_{$what}"])) { $item["{$id_to}_{$what}"] = $source["{$id_from}_{$what}"]; } } } } } // Atom elements to RSS elements $this->normalize_element($item, 'author', $item['dc'], 'creator', 'normalize_atom_person'); $this->normalize_element($item, 'contributor', $item['dc'], 'contributor', 'normalize_atom_person'); $this->normalize_element($item, 'summary', $item, 'description'); $this->normalize_element($item, 'atom_content', $item['content'], 'encoded'); $this->normalize_element($item, 'link_enclosure', $item, 'enclosure', 'normalize_enclosure'); // Categories if (isset($item['category#'])) { // Atom 1.0 categories to dc:subject and RSS 2.0 categories $this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category'); } elseif (isset($item['dc']['subject#'])) { // dc:subject to Atom 1.0 and RSS 2.0 categories $this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject'); } // Normalized item timestamp $atom_date = isset($item['published']) ? $item['published'] : $item['updated']; if ($atom_date) { $epoch = @parse_w3cdtf($atom_date); if ($epoch and $epoch > 0) { $item['date_timestamp'] = $epoch; } } $this->items[$i] = $item; } } elseif ($this->is_rss()) { // RSS elements to Atom elements $this->normalize_element($this->channel, 'description', $this->channel, 'tagline'); // Atom 0.3 $this->normalize_element($this->channel, 'description', $this->channel, 'subtitle'); // Atom 1.0 (yay wordsmithing!) $this->normalize_element($this->image, 'url', $this->channel, 'logo'); for ($i = 0; $i < count($this->items); $i++) { $item = $this->items[$i]; // RSS elements to Atom elements $this->normalize_element($item, 'description', $item, 'summary'); $this->normalize_element($item, 'enclosure', $item, 'link_enclosure', 'normalize_enclosure'); // Categories if (isset($item['category#'])) { // RSS 2.0 categories to dc:subject and Atom 1.0 categories $this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category'); } elseif (isset($item['dc']['subject#'])) { // dc:subject to Atom 1.0 and RSS 2.0 categories $this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject'); } // Normalized item timestamp if ($this->is_rss() == '1.0' and isset($item['dc']['date'])) { $epoch = @parse_w3cdtf($item['dc']['date']); if ($epoch and $epoch > 0) { $item['date_timestamp'] = $epoch; } } elseif (isset($item['pubdate'])) { $epoch = @strtotime($item['pubdate']); if ($epoch > 0) { $item['date_timestamp'] = $epoch; } } $this->items[$i] = $item; } } }
function update_rss_feed_real($link, $feed, $ignore_daemon = false) { global $memcache; if (!$_REQUEST["daemon"] && !$ignore_daemon) { return false; } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: start"); } if (!$ignore_daemon) { if (DB_TYPE == "pgsql") { $updstart_thresh_qpart = "(ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < NOW() - INTERVAL '120 seconds')"; } else { $updstart_thresh_qpart = "(ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < DATE_SUB(NOW(), INTERVAL 120 SECOND))"; } $result = db_query($link, "SELECT id,update_interval,auth_login,\n\t\t\t\tauth_pass,cache_images,update_method\n\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}' AND {$updstart_thresh_qpart}"); } else { $result = db_query($link, "SELECT id,update_interval,auth_login,\n\t\t\t\tfeed_url,auth_pass,cache_images,update_method,last_updated\n\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}'"); } if (db_num_rows($result) == 0) { if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: feed {$feed} NOT FOUND/SKIPPED"); } return false; } $update_method = db_fetch_result($result, 0, "update_method"); $last_updated = db_fetch_result($result, 0, "last_updated"); db_query($link, "UPDATE ttrss_feeds SET last_update_started = NOW()\n\t\t\tWHERE id = '{$feed}'"); $auth_login = db_fetch_result($result, 0, "auth_login"); $auth_pass = db_fetch_result($result, 0, "auth_pass"); if (ALLOW_SELECT_UPDATE_METHOD) { if (ENABLE_SIMPLEPIE) { $use_simplepie = $update_method != 1; } else { $use_simplepie = $update_method == 2; } } else { $use_simplepie = ENABLE_SIMPLEPIE; } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("use simplepie: {$use_simplepie} (feed setting: {$update_method})\n"); } if (!$use_simplepie) { $auth_login = urlencode($auth_login); $auth_pass = urlencode($auth_pass); } $update_interval = db_fetch_result($result, 0, "update_interval"); $cache_images = sql_bool_to_bool(db_fetch_result($result, 0, "cache_images")); $fetch_url = db_fetch_result($result, 0, "feed_url"); if ($update_interval < 0) { return; } $feed = db_escape_string($feed); if ($auth_login && $auth_pass) { $url_parts = array(); preg_match("/(^[^:]*):\\/\\/(.*)/", $fetch_url, $url_parts); if ($url_parts[1] && $url_parts[2]) { $fetch_url = $url_parts[1] . "://{$auth_login}:{$auth_pass}@" . $url_parts[2]; } } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: fetching [{$fetch_url}]..."); } if (!defined('DAEMON_EXTENDED_DEBUG') && !$_REQUEST['xdebug']) { error_reporting(0); } $obj_id = md5("FDATA:{$use_simplepie}:{$fetch_url}"); if ($memcache && ($obj = $memcache->get($obj_id))) { if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: data found in memcache."); } $rss = $obj; } else { if (!$use_simplepie) { $rss = fetch_rss($fetch_url); } else { if (!is_dir(SIMPLEPIE_CACHE_DIR)) { mkdir(SIMPLEPIE_CACHE_DIR); } $rss = new SimplePie(); $rss->set_useragent(SIMPLEPIE_USERAGENT . MAGPIE_USER_AGENT_EXT); # $rss->set_timeout(10); $rss->set_feed_url($fetch_url); $rss->set_output_encoding('UTF-8'); if (SIMPLEPIE_CACHE_IMAGES && $cache_images) { if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("enabling image cache"); } $rss->set_image_handler('./image.php', 'i'); } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("feed update interval (sec): " . get_feed_update_interval($link, $feed) * 60); } if (is_dir(SIMPLEPIE_CACHE_DIR)) { $rss->set_cache_location(SIMPLEPIE_CACHE_DIR); $rss->set_cache_duration(get_feed_update_interval($link, $feed) * 60); } $rss->init(); } if ($memcache && $rss) { $memcache->add($obj_id, $rss, 0, 300); } } // print_r($rss); if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: fetch done, parsing..."); } else { error_reporting(DEFAULT_ERROR_LEVEL); } $feed = db_escape_string($feed); if ($use_simplepie) { $fetch_ok = !$rss->error(); } else { $fetch_ok = !!$rss; } if ($fetch_ok) { if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: processing feed data..."); } // db_query($link, "BEGIN"); $result = db_query($link, "SELECT title,icon_url,site_url,owner_uid\n\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}'"); $registered_title = db_fetch_result($result, 0, "title"); $orig_icon_url = db_fetch_result($result, 0, "icon_url"); $orig_site_url = db_fetch_result($result, 0, "site_url"); $owner_uid = db_fetch_result($result, 0, "owner_uid"); if ($use_simplepie) { $site_url = $rss->get_link(); } else { $site_url = $rss->channel["link"]; } if (get_pref($link, 'ENABLE_FEED_ICONS', $owner_uid, false)) { if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: checking favicon..."); } check_feed_favicon($site_url, $feed, $link); } if (!$registered_title || $registered_title == "[Unknown]") { if ($use_simplepie) { $feed_title = db_escape_string($rss->get_title()); } else { $feed_title = db_escape_string($rss->channel["title"]); } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: registering title: {$feed_title}"); } db_query($link, "UPDATE ttrss_feeds SET \n\t\t\t\t\ttitle = '{$feed_title}' WHERE id = '{$feed}'"); } // weird, weird Magpie if (!$use_simplepie) { if (!$site_url) { $site_url = db_escape_string($rss->channel["link_"]); } } if ($site_url && $orig_site_url != db_escape_string($site_url)) { db_query($link, "UPDATE ttrss_feeds SET \n\t\t\t\t\tsite_url = '{$site_url}' WHERE id = '{$feed}'"); } // print "I: " . $rss->channel["image"]["url"]; if (!$use_simplepie) { $icon_url = $rss->image["url"]; } else { $icon_url = $rss->get_image_url(); } if ($icon_url && !$orig_icon_url != db_escape_string($icon_url)) { $icon_url = db_escape_string($icon_url); db_query($link, "UPDATE ttrss_feeds SET icon_url = '{$icon_url}' WHERE id = '{$feed}'"); } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: loading filters..."); } $filters = load_filters($link, $feed, $owner_uid); if ($use_simplepie) { $iterator = $rss->get_items(); } else { $iterator = $rss->items; if (!$iterator || !is_array($iterator)) { $iterator = $rss->entries; } if (!$iterator || !is_array($iterator)) { $iterator = $rss; } } if (!is_array($iterator)) { /* db_query($link, "UPDATE ttrss_feeds SET last_error = 'Parse error: can\'t find any articles.' WHERE id = '$feed'"); */ // clear any errors and mark feed as updated if fetched okay // even if it's blank if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: entry iterator is not an array, no articles?"); } db_query($link, "UPDATE ttrss_feeds \n\t\t\t\t\tSET last_updated = NOW(), last_error = '' WHERE id = '{$feed}'"); return; // no articles } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: processing articles..."); } foreach ($iterator as $item) { if ($_REQUEST['xdebug'] == 2) { print_r($item); } if ($use_simplepie) { $entry_guid = $item->get_id(); if (!$entry_guid) { $entry_guid = $item->get_link(); } if (!$entry_guid) { $entry_guid = make_guid_from_title($item->get_title()); } } else { $entry_guid = $item["id"]; if (!$entry_guid) { $entry_guid = $item["guid"]; } if (!$entry_guid) { $entry_guid = $item["link"]; } if (!$entry_guid) { $entry_guid = make_guid_from_title($item["title"]); } } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: guid {$entry_guid}"); } if (!$entry_guid) { continue; } $entry_timestamp = ""; if ($use_simplepie) { $entry_timestamp = strtotime($item->get_date()); } else { $rss_2_date = $item['pubdate']; $rss_1_date = $item['dc']['date']; $atom_date = $item['issued']; if (!$atom_date) { $atom_date = $item['updated']; } if ($atom_date != "") { $entry_timestamp = parse_w3cdtf($atom_date); } if ($rss_1_date != "") { $entry_timestamp = parse_w3cdtf($rss_1_date); } if ($rss_2_date != "") { $entry_timestamp = strtotime($rss_2_date); } } if ($entry_timestamp == "" || $entry_timestamp == -1 || !$entry_timestamp) { $entry_timestamp = time(); $no_orig_date = 'true'; } else { $no_orig_date = 'false'; } $entry_timestamp_fmt = strftime("%Y/%m/%d %H:%M:%S", $entry_timestamp); if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: date {$entry_timestamp} [{$entry_timestamp_fmt}]"); } if ($use_simplepie) { $entry_title = $item->get_title(); } else { $entry_title = trim(strip_tags($item["title"])); } if ($use_simplepie) { $entry_link = $item->get_link(); } else { // strange Magpie workaround $entry_link = $item["link_"]; if (!$entry_link) { $entry_link = $item["link"]; } } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: title {$entry_title}"); } if (!$entry_title) { $entry_title = date("Y-m-d H:i:s", $entry_timestamp); } $entry_link = strip_tags($entry_link); if ($use_simplepie) { $entry_content = $item->get_content(); if (!$entry_content) { $entry_content = $item->get_description(); } } else { $entry_content = $item["content:escaped"]; if (!$entry_content) { $entry_content = $item["content:encoded"]; } if (!$entry_content) { $entry_content = $item["content"]["encoded"]; } if (!$entry_content) { $entry_content = $item["content"]; } // Magpie bugs are getting ridiculous if (trim($entry_content) == "Array") { $entry_content = false; } if (!$entry_content) { $entry_content = $item["atom_content"]; } if (!$entry_content) { $entry_content = $item["summary"]; } if (!$entry_content || strlen($entry_content) < strlen($item["description"])) { $entry_content = $item["description"]; } // WTF if (is_array($entry_content)) { $entry_content = $entry_content["encoded"]; if (!$entry_content) { $entry_content = $entry_content["escaped"]; } } } if ($_REQUEST["xdebug"] == 2) { print "update_rss_feed: content: "; print_r(htmlspecialchars($entry_content)); } $entry_content_unescaped = $entry_content; if ($use_simplepie) { $entry_comments = strip_tags($item->data["comments"]); if ($item->get_author()) { $entry_author_item = $item->get_author(); $entry_author = $entry_author_item->get_name(); if (!$entry_author) { $entry_author = $entry_author_item->get_email(); } $entry_author = db_escape_string($entry_author); } } else { $entry_comments = strip_tags($item["comments"]); $entry_author = db_escape_string(strip_tags($item['dc']['creator'])); if ($item['author']) { if (is_array($item['author'])) { if (!$entry_author) { $entry_author = db_escape_string(strip_tags($item['author']['name'])); } if (!$entry_author) { $entry_author = db_escape_string(strip_tags($item['author']['email'])); } } if (!$entry_author) { $entry_author = db_escape_string(strip_tags($item['author'])); } } } if (preg_match('/^[\\t\\n\\r ]*$/', $entry_author)) { $entry_author = ''; } $entry_guid = db_escape_string(strip_tags($entry_guid)); $entry_guid = mb_substr($entry_guid, 0, 250); $result = db_query($link, "SELECT id FROM\tttrss_entries \n\t\t\t\t\tWHERE guid = '{$entry_guid}'"); $entry_content = db_escape_string($entry_content); $content_hash = "SHA1:" . sha1(strip_tags($entry_content)); $entry_title = db_escape_string($entry_title); $entry_link = db_escape_string($entry_link); $entry_comments = mb_substr(db_escape_string($entry_comments), 0, 250); $entry_author = mb_substr($entry_author, 0, 250); if ($use_simplepie) { $num_comments = 0; #FIXME# } else { $num_comments = db_escape_string($item["slash"]["comments"]); } if (!$num_comments) { $num_comments = 0; } // parse <category> entries into tags if ($use_simplepie) { $additional_tags = array(); $additional_tags_src = $item->get_categories(); if (is_array($additional_tags_src)) { foreach ($additional_tags_src as $tobj) { array_push($additional_tags, $tobj->get_term()); } } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: category tags:"); print_r($additional_tags); } } else { $t_ctr = $item['category#']; $additional_tags = false; if ($t_ctr == 0) { $additional_tags = false; } else { if ($t_ctr > 0) { $additional_tags = array($item['category']); if ($item['category@term']) { array_push($additional_tags, $item['category@term']); } for ($i = 0; $i <= $t_ctr; $i++) { if ($item["category#{$i}"]) { array_push($additional_tags, $item["category#{$i}"]); } if ($item["category#{$i}@term"]) { array_push($additional_tags, $item["category#{$i}@term"]); } } } } // parse <dc:subject> elements $t_ctr = $item['dc']['subject#']; if ($t_ctr > 0) { $additional_tags = array($item['dc']['subject']); for ($i = 0; $i <= $t_ctr; $i++) { if ($item['dc']["subject#{$i}"]) { array_push($additional_tags, $item['dc']["subject#{$i}"]); } } } } // enclosures $enclosures = array(); if ($use_simplepie) { $encs = $item->get_enclosures(); if (is_array($encs)) { foreach ($encs as $e) { $e_item = array($e->link, $e->type, $e->length); array_push($enclosures, $e_item); } } } else { // <enclosure> $e_ctr = $item['enclosure#']; if ($e_ctr > 0) { $e_item = array($item['enclosure@url'], $item['enclosure@type'], $item['enclosure@length']); array_push($enclosures, $e_item); for ($i = 0; $i <= $e_ctr; $i++) { if ($item["enclosure#{$i}@url"]) { $e_item = array($item["enclosure#{$i}@url"], $item["enclosure#{$i}@type"], $item["enclosure#{$i}@length"]); array_push($enclosures, $e_item); } } } // <media:content> // can there be many of those? yes -fox $m_ctr = $item['media']['content#']; if ($m_ctr > 0) { $e_item = array($item['media']['content@url'], $item['media']['content@medium'], $item['media']['content@length']); array_push($enclosures, $e_item); for ($i = 0; $i <= $m_ctr; $i++) { if ($item["media"]["content#{$i}@url"]) { $e_item = array($item["media"]["content#{$i}@url"], $item["media"]["content#{$i}@medium"], $item["media"]["content#{$i}@length"]); array_push($enclosures, $e_item); } } } } # sanitize content $entry_content = sanitize_article_content($entry_content); $entry_title = sanitize_article_content($entry_title); if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: done collecting data [TITLE:{$entry_title}]"); } db_query($link, "BEGIN"); if (db_num_rows($result) == 0) { if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: base guid not found"); } // base post entry does not exist, create it $result = db_query($link, "INSERT INTO ttrss_entries \n\t\t\t\t\t\t\t(title,\n\t\t\t\t\t\t\tguid,\n\t\t\t\t\t\t\tlink,\n\t\t\t\t\t\t\tupdated,\n\t\t\t\t\t\t\tcontent,\n\t\t\t\t\t\t\tcontent_hash,\n\t\t\t\t\t\t\tno_orig_date,\n\t\t\t\t\t\t\tdate_entered,\n\t\t\t\t\t\t\tcomments,\n\t\t\t\t\t\t\tnum_comments,\n\t\t\t\t\t\t\tauthor)\n\t\t\t\t\t\tVALUES\n\t\t\t\t\t\t\t('{$entry_title}', \n\t\t\t\t\t\t\t'{$entry_guid}', \n\t\t\t\t\t\t\t'{$entry_link}',\n\t\t\t\t\t\t\t'{$entry_timestamp_fmt}', \n\t\t\t\t\t\t\t'{$entry_content}', \n\t\t\t\t\t\t\t'{$content_hash}',\n\t\t\t\t\t\t\t{$no_orig_date}, \n\t\t\t\t\t\t\tNOW(), \n\t\t\t\t\t\t\t'{$entry_comments}',\n\t\t\t\t\t\t\t'{$num_comments}',\n\t\t\t\t\t\t\t'{$entry_author}')"); } else { // we keep encountering the entry in feeds, so we need to // update date_entered column so that we don't get horrible // dupes when the entry gets purged and reinserted again e.g. // in the case of SLOW SLOW OMG SLOW updating feeds $base_entry_id = db_fetch_result($result, 0, "id"); db_query($link, "UPDATE ttrss_entries SET date_entered = NOW()\n\t\t\t\t\t\tWHERE id = '{$base_entry_id}'"); } // now it should exist, if not - bad luck then $result = db_query($link, "SELECT \n\t\t\t\t\t\tid,content_hash,no_orig_date,title,\n\t\t\t\t\t\t" . SUBSTRING_FOR_DATE . "(date_entered,1,19) as date_entered,\n\t\t\t\t\t\t" . SUBSTRING_FOR_DATE . "(updated,1,19) as updated,\n\t\t\t\t\t\tnum_comments\n\t\t\t\t\tFROM \n\t\t\t\t\t\tttrss_entries \n\t\t\t\t\tWHERE guid = '{$entry_guid}'"); $entry_ref_id = 0; $entry_int_id = 0; if (db_num_rows($result) == 1) { if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: base guid found, checking for user record"); } // this will be used below in update handler $orig_content_hash = db_fetch_result($result, 0, "content_hash"); $orig_title = db_fetch_result($result, 0, "title"); $orig_num_comments = db_fetch_result($result, 0, "num_comments"); $orig_date_entered = strtotime(db_fetch_result($result, 0, "date_entered")); $ref_id = db_fetch_result($result, 0, "id"); $entry_ref_id = $ref_id; // check for user post link to main table // do we allow duplicate posts with same GUID in different feeds? if (get_pref($link, "ALLOW_DUPLICATE_POSTS", $owner_uid, false)) { $dupcheck_qpart = "AND (feed_id = '{$feed}' OR feed_id IS NULL)"; } else { $dupcheck_qpart = ""; } // error_reporting(0); $article_filters = get_article_filters($filters, $entry_title, $entry_content, $entry_link, $entry_timestamp, $entry_author); if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: article filters: "); if (count($article_filters) != 0) { print_r($article_filters); } } if (find_article_filter($article_filters, "filter")) { db_query($link, "COMMIT"); // close transaction in progress continue; } // error_reporting (DEFAULT_ERROR_LEVEL); $score = calculate_article_score($article_filters); if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: initial score: {$score}"); } $query = "SELECT ref_id, int_id FROM ttrss_user_entries WHERE\n\t\t\t\t\t\t\tref_id = '{$ref_id}' AND owner_uid = '{$owner_uid}'\n\t\t\t\t\t\t\t{$dupcheck_qpart}"; // if ($_REQUEST["xdebug"]) print "$query\n"; $result = db_query($link, $query); // okay it doesn't exist - create user entry if (db_num_rows($result) == 0) { if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: user record not found, creating..."); } if ($score >= -500 && !find_article_filter($article_filters, 'catchup')) { $unread = 'true'; $last_read_qpart = 'NULL'; } else { $unread = 'false'; $last_read_qpart = 'NOW()'; } if (find_article_filter($article_filters, 'mark') || $score > 1000) { $marked = 'true'; } else { $marked = 'false'; } if (find_article_filter($article_filters, 'publish')) { $published = 'true'; } else { $published = 'false'; } $result = db_query($link, "INSERT INTO ttrss_user_entries \n\t\t\t\t\t\t\t\t(ref_id, owner_uid, feed_id, unread, last_read, marked, \n\t\t\t\t\t\t\t\t\tpublished, score) \n\t\t\t\t\t\t\tVALUES ('{$ref_id}', '{$owner_uid}', '{$feed}', {$unread},\n\t\t\t\t\t\t\t\t{$last_read_qpart}, {$marked}, {$published}, '{$score}')"); $result = db_query($link, "SELECT int_id FROM ttrss_user_entries WHERE\n\t\t\t\t\t\t\t\tref_id = '{$ref_id}' AND owner_uid = '{$owner_uid}' AND\n\t\t\t\t\t\t\t\tfeed_id = '{$feed}' LIMIT 1"); if (db_num_rows($result) == 1) { $entry_int_id = db_fetch_result($result, 0, "int_id"); } } else { if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: user record FOUND"); } $entry_ref_id = db_fetch_result($result, 0, "ref_id"); $entry_int_id = db_fetch_result($result, 0, "int_id"); } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: RID: {$entry_ref_id}, IID: {$entry_int_id}"); } $post_needs_update = false; if (get_pref($link, "UPDATE_POST_ON_CHECKSUM_CHANGE", $owner_uid, false) && $content_hash != $orig_content_hash) { // print "<!-- [$entry_title] $content_hash vs $orig_content_hash -->"; $post_needs_update = true; } if (db_escape_string($orig_title) != $entry_title) { $post_needs_update = true; } if ($orig_num_comments != $num_comments) { $post_needs_update = true; } // this doesn't seem to be very reliable // // if ($orig_timestamp != $entry_timestamp && !$orig_no_orig_date) { // $post_needs_update = true; // } // if post needs update, update it and mark all user entries // linking to this post as updated if ($post_needs_update) { if (defined('DAEMON_EXTENDED_DEBUG')) { _debug("update_rss_feed: post {$entry_guid} needs update..."); } // print "<!-- post $orig_title needs update : $post_needs_update -->"; db_query($link, "UPDATE ttrss_entries \n\t\t\t\t\t\t\tSET title = '{$entry_title}', content = '{$entry_content}',\n\t\t\t\t\t\t\t\tcontent_hash = '{$content_hash}',\n\t\t\t\t\t\t\t\tnum_comments = '{$num_comments}'\n\t\t\t\t\t\t\tWHERE id = '{$ref_id}'"); if (get_pref($link, "MARK_UNREAD_ON_UPDATE", $owner_uid, false)) { db_query($link, "UPDATE ttrss_user_entries \n\t\t\t\t\t\t\t\tSET last_read = null, unread = true WHERE ref_id = '{$ref_id}'"); } else { db_query($link, "UPDATE ttrss_user_entries \n\t\t\t\t\t\t\t\tSET last_read = null WHERE ref_id = '{$ref_id}' AND unread = false"); } } } db_query($link, "COMMIT"); if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: assigning labels..."); } assign_article_to_labels($link, $entry_ref_id, $article_filters, $owner_uid); if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: looking for enclosures..."); } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { print_r($enclosures); } db_query($link, "BEGIN"); foreach ($enclosures as $enc) { $enc_url = db_escape_string($enc[0]); $enc_type = db_escape_string($enc[1]); $enc_dur = db_escape_string($enc[2]); $result = db_query($link, "SELECT id FROM ttrss_enclosures\n\t\t\t\t\t\tWHERE content_url = '{$enc_url}' AND post_id = '{$entry_ref_id}'"); if (db_num_rows($result) == 0) { db_query($link, "INSERT INTO ttrss_enclosures\n\t\t\t\t\t\t\t(content_url, content_type, title, duration, post_id) VALUES\n\t\t\t\t\t\t\t('{$enc_url}', '{$enc_type}', '', '{$enc_dur}', '{$entry_ref_id}')"); } } db_query($link, "COMMIT"); if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: looking for tags..."); } /* taaaags */ // <a href="..." rel="tag">Xorg</a>, // $entry_tags = null; preg_match_all("/<a.*?rel=['\"]tag['\"].*?>([^<]+)<\\/a>/i", $entry_content_unescaped, $entry_tags); /* print "<p><br/>$entry_title : $entry_content_unescaped<br>"; print_r($entry_tags); print "<br/></p>"; */ $entry_tags = $entry_tags[1]; # check for manual tags foreach ($article_filters as $f) { if ($f[0] == "tag") { $manual_tags = trim_array(split(",", $f[1])); foreach ($manual_tags as $tag) { if (tag_is_valid($tag)) { array_push($entry_tags, $tag); } } } } $boring_tags = trim_array(split(",", mb_strtolower(get_pref($link, 'BLACKLISTED_TAGS', $owner_uid, ''), 'utf-8'))); if ($additional_tags && is_array($additional_tags)) { foreach ($additional_tags as $tag) { if (tag_is_valid($tag) && array_search($tag, $boring_tags) === FALSE) { array_push($entry_tags, $tag); } } } // print "<p>TAGS: "; print_r($entry_tags); print "</p>"; if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { print_r($entry_tags); } if (count($entry_tags) > 0) { db_query($link, "BEGIN"); foreach ($entry_tags as $tag) { $tag = sanitize_tag($tag); $tag = db_escape_string($tag); if (!tag_is_valid($tag)) { continue; } $result = db_query($link, "SELECT id FROM ttrss_tags\t\t\n\t\t\t\t\t\t\t\tWHERE tag_name = '{$tag}' AND post_int_id = '{$entry_int_id}' AND \n\t\t\t\t\t\t\t\towner_uid = '{$owner_uid}' LIMIT 1"); // print db_fetch_result($result, 0, "id"); if ($result && db_num_rows($result) == 0) { db_query($link, "INSERT INTO ttrss_tags \n\t\t\t\t\t\t\t\t\t(owner_uid,tag_name,post_int_id)\n\t\t\t\t\t\t\t\t\tVALUES ('{$owner_uid}','{$tag}', '{$entry_int_id}')"); } } db_query($link, "COMMIT"); } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: article processed"); } } if (!$last_updated) { if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: new feed, catching it up..."); } catchup_feed($link, $feed, false, $owner_uid); } purge_feed($link, $feed, 0); db_query($link, "UPDATE ttrss_feeds \n\t\t\t\tSET last_updated = NOW(), last_error = '' WHERE id = '{$feed}'"); // db_query($link, "COMMIT"); } else { if ($use_simplepie) { $error_msg = mb_substr($rss->error(), 0, 250); } else { $error_msg = mb_substr(magpie_error(), 0, 250); } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: error fetching feed: {$error_msg}"); } $error_msg = db_escape_string($error_msg); db_query($link, "UPDATE ttrss_feeds SET last_error = '{$error_msg}', \n\t\t\t\t\tlast_updated = NOW() WHERE id = '{$feed}'"); } if ($use_simplepie) { unset($rss); } if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) { _debug("update_rss_feed: done"); } }
$target = "_main"; if (strstr($_SERVER['HTTP_USER_AGENT'], "Opera")) { $target = "_blank"; } elseif (strstr($_SERVER['HTTP_USER_AGENT'], "Gecko")) { $target = "_content"; } $sql = "SELECT id FROM user WHERE id=" . $_GET['p'] . " AND public=1"; $res = mysql_query($sql); $row = mysql_fetch_array($res); if ($row['id'] != $_GET['p']) { die("Diese Feed-Sammlung ist nicht öffentlich."); } $sql = "SELECT i.url AS iurl, i.title AS ititle, i.date AS idate, f.title AS ftitle, f.url AS furl FROM items AS i LEFT JOIN user_feeds ON i.feed_id = user_feeds.feed_id LEFT JOIN feeds AS f ON i.feed_id = f.id WHERE user_feeds.user_id = " . $_GET['p'] . " ORDER BY i.date DESC LIMIT 10"; $res = mysql_query($sql) or die(mysql_error() . " {$sql}"); while ($row = mysql_fetch_array($res)) { $stamp = parse_w3cdtf($row['idate']); $stamp = dst_test($stamp); $ftime = date("H:i", $stamp); $ftitle = $row['ftitle']; if (strlen($ftitle) > 20) { $ftitle = substr($ftitle, 0, 16) . "..."; } $ititle = $row['ititle']; if (strlen($ititle) > 25) { $ititle = substr($ititle, 0, 22) . "..."; } echo '<p>• [' . $ftime . '] ' . $ftitle . '<br />'; echo '<a target="' . $target . '" href="' . $row['iurl'] . '" title="' . $row['ititle'] . '">' . $ititle . '</a></p>'; } ?> <br />Powered by <a target="_content" href="http://" . ERONA_URL . ""><strong>eRONA</strong></a>
// WRAPPING EVERYTHING BUT HEADER & FOOTER. ?> <section class="wrap start-wrap group"> <!--<div class="colwrap"> <img src="<?php echo BASE_URL; ?> images/Logo-2012.png" id="icpc-live-logo" /> </div>--> <div class="col2"> <?php foreach ($rss->items as $item) { $published = parse_w3cdtf($item['pubdate']); ?> <article class="post"> <header class="entry-header"> <h1 class="entry-title"><?php echo $item['title']; ?> </h1> <small class="pubdate"><?php echo date("D, j M", strtotime($item['pubdate'])); ?> </small> </header><!-- .entry-header --> <div class="entry-content"> <?php
function RSSListUpdate(&$irc) { global $lastupdatetime; global $SRB2MS_mute; if ($SRB2MS_mute) { return; } $RSS10content = $this->GenFeed(); $SRB2MSRSS10 = new MagpieRSS($RSS10content); if ($SRB2MSRSS10) { //$irc->message(SMARTIRC_TYPE_CHANNEL, '#srb2fun', 'Running SRB2 netgames '); foreach ($SRB2MSRSS10->items as $item) { if ($item['title'] == "No servers") { // NOP } elseif ($item['title'] == "No master server") { // NOP } else { $published = parse_w3cdtf($item['dc']['date']); if ($published >= $lastupdatetime) { $title = $item['title']; $serveraddress = $item['srb2ms']['address']; $serverport = $item['srb2ms']['port']; $serverversion = $item['srb2ms']['version']; $irc->message(SMARTIRC_TYPE_CHANNEL, '#srb2fun', "New Server, {$serveraddress}:{$serverport} Name: {$title} Version: {$serverversion}"); //$irc->message(SMARTIRC_TYPE_CHANNEL, '#srb2general', "New Server, Name: $title $description"); } else { // NOP } } } $today = getdate(); // update time $lastupdatetime = mktime($today['hours'], $today['minutes'], 0, $today['mon'], $today['mday'], $today['year']); } else { $irc->message(SMARTIRC_TYPE_CHANNEL, '#srb2fun', '.magpie_error()'); $irc->message(SMARTIRC_TYPE_CHANNEL, '#srb2fun', 'The SRB2 MasterServer RSS feed is not up'); } }
function normalize() { // if atom populate rss fields if ($this->is_atom()) { $this->channel['description'] = $this->channel['tagline']; for ($i = 0; $i < count($this->items); $i++) { $item = $this->items[$i]; if (isset($item['summary'])) { $item['description'] = $item['summary']; } if (isset($item['atom_content'])) { $item['content']['encoded'] = $item['atom_content']; } $atom_date = isset($item['issued']) ? $item['issued'] : $item['modified']; if ($atom_date) { $epoch = @parse_w3cdtf($atom_date); if ($epoch and $epoch > 0) { $item['date_timestamp'] = $epoch; } } $this->items[$i] = $item; } } elseif ($this->is_rss()) { $this->channel['tagline'] = $this->channel['description']; for ($i = 0; $i < count($this->items); $i++) { $item = $this->items[$i]; if (isset($item['description'])) { $item['summary'] = $item['description']; } if (isset($item['content']['encoded'])) { $item['atom_content'] = $item['content']['encoded']; } if ($this->is_rss() == '1.0' and isset($item['dc']['date'])) { $epoch = @parse_w3cdtf($item['dc']['date']); if ($epoch and $epoch > 0) { $item['date_timestamp'] = $epoch; } } elseif (isset($item['pubdate'])) { $epoch = @strtotime($item['pubdate']); if ($epoch > 0) { $item['date_timestamp'] = $epoch; } } $this->items[$i] = $item; } } }
function updated($fallback = true, $default = -1) { $epoch = null; # As far as I know, only dcterms and Atom have reliable ways to # specify when something was *modified* last. If neither is # available, then we'll try to get the time of publication. if (isset($this->item['dc']['modified'])) { // Not really correct $epoch = @parse_w3cdtf($this->item['dc']['modified']); } elseif (isset($this->item['dcterms']['modified'])) { // Dublin Core extensions $epoch = @parse_w3cdtf($this->item['dcterms']['modified']); } elseif (isset($this->item['modified'])) { // Atom 0.3 $epoch = @parse_w3cdtf($this->item['modified']); } elseif (isset($this->item['updated'])) { // Atom 1.0 $epoch = @parse_w3cdtf($this->item['updated']); } elseif ($fallback) { // Fall back to issued / dc:date $epoch = $this->published(false, $default); } # If everything failed, then default to the current time. if (is_null($epoch)) { if (-1 == $default) { $epoch = time(); } else { $epoch = $default; } } return $epoch; }