Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Richard Beales 2013-03-21 18:57:21 +00:00
commit 96f19f11d7
53 changed files with 7326 additions and 4114 deletions

View file

@ -155,3 +155,7 @@ div.cdmContentInner p {
.Unread div.cdmHeader {
font-weight : bold;
}
div.cdmContentInner iframe {
min-width : 50%;
}

View file

@ -655,6 +655,11 @@ class API extends Handler {
$headline_row["always_display_attachments"] = sql_bool_to_bool($line["always_display_enclosures"]);
global $pluginhost;
foreach ($pluginhost->get_hooks($pluginhost::HOOK_RENDER_ARTICLE_API) as $p) {
$headline_row = $p->hook_render_article_api($headline_row);
}
array_push($headlines, $headline_row);
}

View file

@ -637,8 +637,7 @@ class Feeds extends Handler_Protected {
$always_display_enclosures = sql_bool_to_bool($line["always_display_enclosures"]);
$reply['content'] .= format_article_enclosures($this->link, $id, $always_display_enclosures,
$line["content"]);
$reply['content'] .= format_article_enclosures($this->link, $id, $always_display_enclosures, $line["content"], sql_bool_to_bool($line["hide_images"]));
$reply['content'] .= "</div>";

View file

@ -22,6 +22,7 @@ class PluginHost {
const HOOK_RENDER_ARTICLE_CDM = 11;
const HOOK_FEED_FETCHED = 12;
const HOOK_SANITIZE = 13;
const HOOK_RENDER_ARTICLE_API = 14;
const KIND_ALL = 1;
const KIND_SYSTEM = 2;
@ -171,7 +172,7 @@ class PluginHost {
}
function add_command($command, $description, $sender) {
$command = "-" . str_replace("-", "_", strtolower($command));
$command = str_replace("-", "_", strtolower($command));
$this->commands[$command] = array("description" => $description,
"class" => $sender);
@ -201,7 +202,7 @@ class PluginHost {
function run_commands($args) {
foreach ($this->get_commands() as $command => $data) {
if (in_array($command, $args)) {
if (isset($args[$command])) {
$command = str_replace("-", "", $command);
$data["class"]->$command($args);
}

BIN
images/favicon-72px.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 772 B

View file

@ -41,13 +41,21 @@ function db_connect($host, $user, $pass, $db) {
}
}
function db_escape_string($s, $strip_tags = true) {
function db_escape_string($s, $strip_tags = true, $link = NULL) {
if ($strip_tags) $s = strip_tags($s);
if (DB_TYPE == "pgsql") {
return pg_escape_string($s);
if ($link) {
return pg_escape_string($link, $s);
} else {
return pg_escape_string($s);
}
} else {
return mysql_real_escape_string($s);
if ($link) {
return mysql_real_escape_string($s, $link);
} else {
return mysql_real_escape_string($s);
}
}
}

View file

@ -44,6 +44,7 @@
$tr = array(
"auto" => "Detect automatically",
"ca_CA" => "Català",
"cs_CZ" => "Česky",
"en_US" => "English",
"es_ES" => "Español",
"de_DE" => "Deutsch",
@ -122,14 +123,24 @@
* @return void
*/
function _debug($msg) {
if (defined('QUIET') && QUIET) {
return;
}
$ts = strftime("%H:%M:%S", time());
if (function_exists('posix_getpid')) {
$ts = "$ts/" . posix_getpid();
}
print "[$ts] $msg\n";
if (!(defined('QUIET') && QUIET)) {
print "[$ts] $msg\n";
}
if (defined('LOGFILE')) {
$fp = fopen(LOGFILE, 'a+');
if ($fp) {
fputs($fp, "[$ts] $msg\n");
fclose($fp);
}
}
} // function _debug
/**
@ -1820,11 +1831,6 @@
function make_init_params($link) {
$params = array();
$params["sign_progress"] = "images/indicator_white.gif";
$params["sign_progress_tiny"] = "images/indicator_tiny.gif";
$params["sign_excl"] = "images/sign_excl.svg";
$params["sign_info"] = "images/sign_info.svg";
foreach (array("ON_CATCHUP_SHOW_NEXT_FEED", "HIDE_READ_FEEDS",
"ENABLE_FEED_CATS", "FEEDS_SORT_BY_UNREAD", "CONFIRM_FEED_CATCHUP",
"CDM_AUTO_CATCHUP", "FRESH_ARTICLE_MAX_AGE", "DEFAULT_ARTICLE_LIMIT",
@ -1885,7 +1891,8 @@
"select_article_cursor" => __("Select article under cursor"),
"email_article" => __("Email article"),
"close_article" => __("Close/collapse article"),
"toggle_widescreen" => __("Toggle widescreen mode")),
"toggle_widescreen" => __("Toggle widescreen mode"),
"toggle_embed_original" => __("Toggle embed original")),
__("Article selection") => array(
"select_all" => __("Select all articles"),
"select_unread" => __("Select unread"),
@ -1948,6 +1955,7 @@
"*(38)|Shift+up" => "article_scroll_up",
"*(40)|Shift+down" => "article_scroll_down",
"a *w" => "toggle_widescreen",
"a e" => "toggle_embed_original",
"e" => "email_article",
"a q" => "close_article",
// "article_selection" => array(
@ -2021,6 +2029,8 @@
$data['last_article_id'] = getLastArticleId($link);
$data['cdm_expanded'] = get_pref($link, 'CDM_EXPANDED');
$data['dep_ts'] = calculate_dep_timestamp();
if (file_exists(LOCK_DIRECTORY . "/update_daemon.lock")) {
$data['daemon_is_running'] = (int) file_is_locked("update_daemon.lock");
@ -2501,7 +2511,7 @@
"label_cache," .
"link," .
"last_read," .
"hide_images," .
"(SELECT hide_images FROM ttrss_feeds WHERE id = feed_id) AS hide_images," .
"last_marked, last_published, " .
SUBSTRING_FOR_DATE . "(last_read,1,19) as last_read_noms," .
$since_id_part .
@ -2941,6 +2951,7 @@
$result = db_query($link, "SELECT id,title,link,content,feed_id,comments,int_id,
".SUBSTRING_FOR_DATE."(updated,1,16) as updated,
(SELECT site_url FROM ttrss_feeds WHERE id = feed_id) as site_url,
(SELECT hide_images FROM ttrss_feeds WHERE id = feed_id) as hide_images,
num_comments,
tag_cache,
author,
@ -3122,7 +3133,7 @@
$rv['content'] .= $line["content"];
$rv['content'] .= format_article_enclosures($link, $id,
$always_display_enclosures, $line["content"]);
$always_display_enclosures, $line["content"], $line["hide_images"]);
$rv['content'] .= "</div>";
@ -3585,7 +3596,7 @@
}
function format_article_enclosures($link, $id, $always_display_enclosures,
$article_content) {
$article_content, $hide_images = false) {
$result = get_article_enclosures($link, $id);
$rv = '';
@ -3635,10 +3646,16 @@
if (preg_match("/image/", $entry["type"]) ||
preg_match("/\.(jpg|png|gif|bmp)/i", $entry["filename"])) {
$rv .= "<p><img
alt=\"".htmlspecialchars($entry["filename"])."\"
src=\"" .htmlspecialchars($entry["url"]) . "\"/></p>";
if (!$hide_images) {
$rv .= "<p><img
alt=\"".htmlspecialchars($entry["filename"])."\"
src=\"" .htmlspecialchars($entry["url"]) . "\"/></p>";
} else {
$rv .= "<p><a target=\"_blank\"
href=\"".htmlspecialchars($entry["url"])."\"
>" .htmlspecialchars($entry["url"]) . "</a></p>";
}
}
}
}
@ -4083,4 +4100,16 @@
echo "<script type=\"text/javascript\" charset=\"utf-8\" src=\"$filename?$timestamp\"></script>\n";
}
function calculate_dep_timestamp() {
$files = array_merge(glob("js/*.js"), glob("*.css"));
$max_ts = -1;
foreach ($files as $file) {
if (filemtime($file) > $max_ts) $max_ts = filemtime($file);
}
return $max_ts;
}
?>

View file

@ -1,4 +1,4 @@
<?php # This file has been generated at: Wed Mar 20 15:53:19 MSK 2013
<?php # This file has been generated at: Thu Mar 21 15:10:58 MSK 2013
__("Title");
__("Title or Content");

View file

@ -53,7 +53,7 @@
$expire = time() + $session_expire;
$data = db_escape_string(base64_encode($data), $session_connection);
$data = db_escape_string(base64_encode($data), false, $session_connection);
if ($session_read) {
$query = "UPDATE ttrss_sessions SET data='$data',
@ -96,7 +96,7 @@
db_query($session_connection, $query);
}
if (!SINGLE_USER_MODE && DB_TYPE == "pgsql") {
if (!SINGLE_USER_MODE /* && DB_TYPE == "pgsql" */) {
session_set_save_handler("ttrss_open",
"ttrss_close", "ttrss_read", "ttrss_write",
"ttrss_destroy", "ttrss_gc");

View file

@ -72,6 +72,7 @@
</style>
<link rel="shortcut icon" type="image/png" href="images/favicon.png"/>
<link rel="icon" type="image/png" sizes="72x72" href="images/favicon-72px.png" />
<?php
foreach (array("lib/prototype.js",

View file

@ -165,6 +165,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
if (id.match("CAT:")) {
loading = dojo.doc.createElement('img');
loading.className = 'loadingNode';
loading.src = 'images/blank_icon.gif';
dojo.place(loading, tnode.labelNode, 'after');
tnode.loadingNode = loading;
}

View file

@ -201,13 +201,13 @@ function notify_real(msg, no_hide, n_type) {
n.className = "notify";
} else if (n_type == 2) {
n.className = "notifyProgress";
msg = "<img src='"+getInitParam("sign_progress")+"'> " + msg;
msg = "<img src='images/indicator_white.gif'> " + msg;
} else if (n_type == 3) {
n.className = "notifyError";
msg = "<img src='"+getInitParam("sign_excl")+"'> " + msg;
msg = "<img src='images/sign_excl.svg'> " + msg;
} else if (n_type == 4) {
n.className = "notifyInfo";
msg = "<img src='"+getInitParam("sign_info")+"'> " + msg;
msg = "<img src='images/sign_info.svg'> " + msg;
}
// msg = "<img src='images/live_com_loading.gif'> " + msg;

View file

@ -185,7 +185,7 @@ function updateTitle() {
}
if (global_unread > 0) {
tmp = tmp + " (" + global_unread + ")";
tmp = "(" + global_unread + ") " + tmp;
}
if (window.fluid) {
@ -450,6 +450,12 @@ function parse_runtime_info(data) {
return;
}
if (k == "dep_ts" && parseInt(getInitParam("dep_ts")) > 0) {
if (parseInt(getInitParam("dep_ts")) < parseInt(v)) {
window.location.reload();
}
}
if (k == "daemon_is_running" && v != 1) {
notify_error("<span onclick=\"javascript:explainError(1)\">Update daemon is not running.</span>", true);
return;
@ -790,6 +796,14 @@ function hotkey_handler(e) {
case "collapse_sidebar":
collapse_feedlist();
return false;
case "toggle_embed_original":
if (typeof embedOriginalArticle != "undefined") {
if (getActiveArticleId())
embedOriginalArticle(getActiveArticleId());
} else {
alert(__("Please enable embed_original plugin first."));
}
return false;
case "toggle_widescreen":
if (!isCdmMode()) {
_widescreen_mode = !_widescreen_mode;
@ -932,6 +946,8 @@ function handle_rpc_json(transport, scheduled_call) {
function switchPanelMode(wide) {
try {
if (isCdmMode()) return;
article_id = getActiveArticleId();
if (wide) {

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,13 @@
div.cdmContentInner iframe.embeddedContent {
overflow : hidden;
width : 100%;
height : 600px;
border-width : 0px;
}
div.postContent iframe.embeddedContent {
overflow : hidden;
width : 100%;
height : 100%;
border-width : 0px;
}

View file

@ -0,0 +1,69 @@
function embedOriginalArticle(id) {
try {
var hasSandbox = "sandbox" in document.createElement("iframe");
if (!hasSandbox) {
alert(__("Sorry, your browser does not support sandboxed iframes."));
return;
}
var query = "op=pluginhandler&plugin=embed_original&method=getUrl&id=" +
param_escape(id);
var c = false;
if (isCdmMode()) {
c = $$("div#RROW-" + id + " div[class=cdmContentInner]")[0];
} else if (id == getActiveArticleId()) {
c = $$("div[class=postContent]")[0];
}
if (c) {
var iframe = c.getElementsByClassName("embeddedContent")[0];
if (iframe) {
Element.show(c.firstChild);
c.removeChild(iframe);
if (isCdmMode()) {
cdmScrollToArticleId(id, true);
}
return;
}
}
new Ajax.Request("backend.php", {
parameters: query,
onComplete: function(transport) {
var ti = JSON.parse(transport.responseText);
if (ti) {
var iframe = new Element("iframe", {
class: "embeddedContent",
src: ti.url,
sandbox: 'allow-scripts',
});
if (c) {
Element.hide(c.firstChild);
if (c.firstChild.nextSibling)
c.insertBefore(iframe, c.firstChild.nextSibling);
else
c.appendChild(iframe);
if (isCdmMode()) {
cdmScrollToArticleId(id, true);
}
}
}
} });
} catch (e) {
exception_error("embedOriginalArticle", e);
}
}

View file

@ -0,0 +1,56 @@
<?php
class Embed_Original extends Plugin {
private $link;
private $host;
function init($host) {
$this->link = $host->get_link();
$this->host = $host;
$host->add_hook($host::HOOK_ARTICLE_BUTTON, $this);
}
function about() {
return array(1.0,
"Try to display original article content inside tt-rss",
"fox");
}
function get_js() {
return file_get_contents(dirname(__FILE__) . "/init.js");
}
function get_css() {
return file_get_contents(dirname(__FILE__) . "/init.css");
}
function hook_article_button($line) {
$id = $line["id"];
$rv = "<img src=\"plugins/embed_original/button.png\"
class='tagsPic' style=\"cursor : pointer\"
onclick=\"embedOriginalArticle($id)\"
title='".__('Toggle embed original')."'>";
return $rv;
}
function getUrl() {
$id = db_escape_string($_REQUEST['id']);
$result = db_query($this->link, "SELECT link
FROM ttrss_entries, ttrss_user_entries
WHERE id = '$id' AND ref_id = id AND owner_uid = " .$_SESSION['uid']);
$url = "";
if (db_num_rows($result) != 0) {
$url = db_fetch_result($result, 0, "link");
}
print json_encode(array("url" => $url, "id" => $id));
}
}
?>

View file

@ -1,73 +0,0 @@
/* fix dijit */
:focus {
outline: none;
}
input[type="search"] {
-webkit-appearance: none;
}
.claro .dijitToolbar .dijitButton .dijitButtonNode,
.claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
.claro .dijitToolbar .dijitComboButton .dijitButtonNode,
.claro .dijitToolbar .dijitToggleButton .dijitButtonNode,
.claro .dijitToolbar .dijitComboBox .dijitButtonNode {
-moz-transition: background-color, border-color, color;
-webkit-transition-property: background-color, border-color, color;
transition: background-color, border-color, color;
}
/* some style */
body#ttrssMain,
a,
.titleWrap .title {
color: #444;
}
a:hover,
.Unread .titleWrap .title,
.Selected .titleWrap .title,
html div.cdmContent a {
color: #15c;
}
#feeds-holder,
#content-wrap,
#headlines-frame {
border: none;
}
#ttrssMain #headlines-toolbar,
#ttrssMain .dijitToolbar,
#ttrssMain .cdmHeader {
background: #fff;
border-color: transparent;
}
#ttrssMain #headlines-toolbar {
border-color: #ebebeb;
}
#ttrssMain .cdm {
margin: 5px 25px 10px 5px;
border: 1px solid #ddd !important;
box-shadow: 0 0 4px rgba(0,0,0,.1);
background: #fff !important;
}
#ttrssMain .cdm.Selected {
border-left-color: #4d90f0 !important;
background: #fff !important;
}
#ttrssMain .cdmFeedTitle {
border-color: #ebebeb;
background: #fff;
font-size: 1.2em;
font-weight: bold;
}
#headlines-frame .cdmFooter {
border-top: 1px solid #ebebeb;
background: #fafafa;
}
.titleWrap .title {
font-size: 1.5em;
font-weight: bold;
}
div.cdmHeader span.hlFeed {
padding-top: .5em;
}

View file

@ -1,27 +0,0 @@
<?php
class GoogleReaderTheme extends Plugin {
private $link;
private $host;
function about() {
return array(1.0,
"Make tt-rss look similar to Google Reader",
"levito");
}
function init($host) {
$this->link = $host->get_link();
$this->host = $host;
if ($_SESSION["uid"]) {
// force-enable combined mode
set_pref($this->link, "COMBINED_DISPLAY_MODE", true, $_SESSION["uid"]);
}
}
function get_css() {
return file_get_contents(dirname(__FILE__) . "/init.css");
}
}
?>

View file

@ -31,6 +31,7 @@
<?php print_user_stylesheet($link) ?>
<link rel="shortcut icon" type="image/png" href="images/favicon.png"/>
<link rel="icon" type="image/png" sizes="72x72" href="images/favicon-72px.png" />
<?php
foreach (array("lib/prototype.js",

View file

@ -1193,3 +1193,7 @@ div.postContent p {
.Unread div.hlTitle {
font-weight : bold;
}
div.postContent iframe {
min-width : 50%;
}

View file

@ -22,9 +22,27 @@
init_connection($link);
$op = $argv;
$longopts = array("feeds",
"feedbrowser",
"daemon",
"daemon-loop",
"task:",
"cleanup-tags",
"quiet",
"log:",
"indexes",
"convert-filters",
"force-update",
"list-plugins",
"help");
if (count($argv) == 0 && !defined('STDIN')) {
foreach ($pluginhost->get_commands() as $command => $data) {
array_push($longopts, $command);
}
$options = getopt("", $longopts);
if (count($options) == 0 && !defined('STDIN')) {
?> <html>
<head>
<title>Tiny Tiny RSS data update script.</title>
@ -43,36 +61,48 @@
exit;
}
if (count($argv) == 1 || in_array("-help", $op) ) {
if (count($options) == 0 || isset($options["help"]) ) {
print "Tiny Tiny RSS data update script.\n\n";
print "Options:\n";
print " -feeds - update feeds\n";
print " -feedbrowser - update feedbrowser\n";
print " -daemon - start single-process update daemon\n";
print " -cleanup-tags - perform tags table maintenance\n";
print " -quiet - don't show messages\n";
print " -indexes - recreate missing schema indexes\n";
print " -convert-filters - convert type1 filters to type2\n";
print " -force-update - force update of all feeds\n";
print " -list-plugins - list all available plugins\n";
print " -help - show this help\n";
print " --feeds - update feeds\n";
print " --feedbrowser - update feedbrowser\n";
print " --daemon - start single-process update daemon\n";
print " --task N - create lockfile using this task id\n";
print " --cleanup-tags - perform tags table maintenance\n";
print " --quiet - don't output messages to stdout\n";
print " --log FILE - log messages to FILE\n";
print " --indexes - recreate missing schema indexes\n";
print " --convert-filters - convert type1 filters to type2\n";
print " --force-update - force update of all feeds\n";
print " --list-plugins - list all available plugins\n";
print " --help - show this help\n";
print "Plugin options:\n";
foreach ($pluginhost->get_commands() as $command => $data) {
printf(" %-19s - %s\n", "$command", $data["description"]);
printf(" --%-19s - %s\n", "$command", $data["description"]);
}
return;
}
define('QUIET', in_array("-quiet", $op));
define('QUIET', isset($options['quiet']));
if (!in_array("-daemon", $op)) {
if (isset($options["log"])) {
_debug("Logging to " . $options["log"]);
define('LOGFILE', $options["log"]);
}
if (!isset($options["daemon"])) {
$lock_filename = "update.lock";
} else {
$lock_filename = "update_daemon.lock";
}
if (isset($options["task"])) {
_debug("Using task id " . $options["task"]);
$lock_filename = $lock_filename . "-task_" . $options["task"];
}
$lock_handle = make_lockfile($lock_filename);
$must_exit = false;
@ -82,7 +112,14 @@
"Maybe another update process is already running.\n");
}
if (in_array("-feeds", $op)) {
if (isset($options["force-update"])) {
_debug("marking all feeds as needing update...");
db_query($link, "UPDATE ttrss_feeds SET last_update_started = '1970-01-01',
last_updated = '1970-01-01'");
}
if (isset($options["feeds"])) {
// Update all feeds needing a update.
update_daemon_common($link);
@ -100,21 +137,20 @@
$pluginhost->run_hooks($pluginhost::HOOK_UPDATE_TASK, "hook_update_task", $op);
}
if (in_array("-feedbrowser", $op)) {
if (isset($options["feedbrowser"])) {
$count = update_feedbrowser_cache($link);
print "Finished, $count feeds processed.\n";
}
if (in_array("-daemon", $op)) {
$op = array_diff($op, array("-daemon"));
if (isset($options["daemon"])) {
while (true) {
passthru(PHP_EXECUTABLE . " " . implode(' ', $op) . " -daemon-loop");
passthru(PHP_EXECUTABLE . " " . $argv[0] ." --daemon-loop");
_debug("Sleeping for " . DAEMON_SLEEP_INTERVAL . " seconds...");
sleep(DAEMON_SLEEP_INTERVAL);
}
}
if (in_array("-daemon-loop", $op)) {
if (isset($options["daemon-loop"])) {
if (!make_stampfile('update_daemon.stamp')) {
die("error: unable to create stampfile\n");
}
@ -140,12 +176,12 @@
}
if (in_array("-cleanup-tags", $op)) {
if (isset($options["cleanup-tags"])) {
$rc = cleanup_tags($link, 14, 50000);
_debug("$rc tags deleted.\n");
}
if (in_array("-indexes", $op)) {
if (isset($options["indexes"])) {
_debug("PLEASE BACKUP YOUR DATABASE BEFORE PROCEEDING!");
_debug("Type 'yes' to continue.");
@ -200,7 +236,7 @@
_debug("all done.");
}
if (in_array("-convert-filters", $op)) {
if (isset($options["convert-filters"])) {
_debug("WARNING: this will remove all existing type2 filters.");
_debug("Type 'yes' to continue.");
@ -251,14 +287,7 @@
}
if (in_array("-force-update", $op)) {
_debug("marking all feeds as needing update...");
db_query($link, "UPDATE ttrss_feeds SET last_update_started = '1970-01-01',
last_updated = '1970-01-01'");
}
if (in_array("-list-plugins", $op)) {
if (isset($options["list-plugins"])) {
$tmppluginhost = new PluginHost($link);
$tmppluginhost->load_all($tmppluginhost::KIND_ALL);
$enabled = array_map("trim", explode(",", PLUGINS));
@ -280,7 +309,7 @@
}
$pluginhost->run_commands($op);
$pluginhost->run_commands($options);
db_close($link);

View file

@ -14,9 +14,6 @@
define('DAEMON_EXTENDED_DEBUG', true);
}
define('PURGE_INTERVAL', 3600); // seconds
define('MAX_CHILD_RUNTIME', 600); // seconds
require_once "functions.php";
require_once "rssfuncs.php";
require_once "sanity_check.php";
@ -24,8 +21,11 @@
require_once "db.php";
require_once "db-prefs.php";
// defaults
define('PURGE_INTERVAL', 3600); // seconds
define('MAX_CHILD_RUNTIME', 600); // seconds
define('MAX_JOBS', 2);
define('SPAWN_INTERVAL', DAEMON_SLEEP_INTERVAL);
define('SPAWN_INTERVAL', DAEMON_SLEEP_INTERVAL); // seconds
if (!function_exists('pcntl_fork')) {
die("error: This script requires PHP compiled with PCNTL module.\n");
@ -118,6 +118,46 @@
pcntl_signal(SIGCHLD, 'sigchld_handler');
$longopts = array("log:",
"tasks:",
"interval",
"help");
$options = getopt("", $longopts);
if (isset($options["help"]) ) {
print "Tiny Tiny RSS update daemon.\n\n";
print "Options:\n";
print " --log FILE - log messages to FILE\n";
print " --tasks N - amount of update tasks to spawn\n";
print " default: " . MAX_JOBS . "\n";
print " --interval N - task spawn interval\n";
print " default: " . SPAWN_INTERVAL . " seconds.\n";
print " --quiet - don't output messages to stdout\n";
return;
}
define('QUIET', isset($options['quiet']));
if (isset($options["tasks"])) {
_debug("Set to spawn " . $options["tasks"] . " children.");
$max_jobs = $option["tasks"];
} else {
$max_jobs = MAX_JOBS;
}
if (isset($options["interval"])) {
_debug("Spawn interval: " . $options["interval"] . " seconds.");
$spawn_interval = $option["interval"];
} else {
$spawn_interval = SPAWN_INTERVAL;
}
if (isset($options["log"])) {
_debug("Logging to " . $options["log"]);
define('LOGFILE', $options["log"]);
}
if (file_is_locked("update_daemon.lock")) {
die("error: Can't create lockfile. ".
"Maybe another daemon is already running.\n");
@ -142,20 +182,20 @@
while (true) {
// Since sleep is interupted by SIGCHLD, we need another way to
// respect the SPAWN_INTERVAL
$next_spawn = $last_checkpoint + SPAWN_INTERVAL - time();
// respect the spawn interval
$next_spawn = $last_checkpoint + $spawn_interval - time();
if ($next_spawn % 10 == 0) {
$running_jobs = count($children);
_debug("[MASTER] active jobs: $running_jobs, next spawn at $next_spawn sec.");
}
if ($last_checkpoint + SPAWN_INTERVAL < time()) {
if ($last_checkpoint + $spawn_interval < time()) {
check_ctimes();
reap_children();
for ($j = count($children); $j < MAX_JOBS; $j++) {
for ($j = count($children); $j < $max_jobs; $j++) {
$pid = pcntl_fork();
if ($pid == -1) {
die("fork failed!\n");