PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/update.php

https://github.com/haharazer/Tiny-Tiny-RSS
PHP | 359 lines | 286 code | 70 blank | 3 comment | 56 complexity | 27bc01b54ed17f039169488cdfedd952 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-2.0, BSD-3-Clause, LGPL-2.0
  1. #!/usr/bin/env php
  2. <?php
  3. set_include_path(dirname(__FILE__) ."/include" . PATH_SEPARATOR .
  4. get_include_path());
  5. define('DISABLE_SESSIONS', true);
  6. chdir(dirname(__FILE__));
  7. require_once "autoload.php";
  8. require_once "functions.php";
  9. require_once "rssfuncs.php";
  10. require_once "config.php";
  11. require_once "sanity_check.php";
  12. require_once "db.php";
  13. require_once "db-prefs.php";
  14. if (!defined('PHP_EXECUTABLE'))
  15. define('PHP_EXECUTABLE', '/usr/bin/php');
  16. init_plugins();
  17. $longopts = array("feeds",
  18. "feedbrowser",
  19. "daemon",
  20. "daemon-loop",
  21. "task:",
  22. "cleanup-tags",
  23. "quiet",
  24. "log:",
  25. "indexes",
  26. "pidlock:",
  27. "update-schema",
  28. "convert-filters",
  29. "force-update",
  30. "list-plugins",
  31. "help");
  32. foreach (PluginHost::getInstance()->get_commands() as $command => $data) {
  33. array_push($longopts, $command . $data["suffix"]);
  34. }
  35. $options = getopt("", $longopts);
  36. if (!is_array($options)) {
  37. die("error: getopt() failed. ".
  38. "Most probably you are using PHP CGI to run this script ".
  39. "instead of required PHP CLI. Check tt-rss wiki page on updating feeds for ".
  40. "additional information.\n");
  41. }
  42. if (count($options) == 0 && !defined('STDIN')) {
  43. ?> <html>
  44. <head>
  45. <title>Tiny Tiny RSS data update script.</title>
  46. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  47. <link rel="stylesheet" type="text/css" href="css/utility.css">
  48. </head>
  49. <body>
  50. <div class="floatingLogo"><img src="images/logo_small.png"></div>
  51. <h1><?php echo __("Tiny Tiny RSS data update script.") ?></h1>
  52. <?php print_error("Please run this script from the command line. Use option \"-help\" to display command help if this error is displayed erroneously."); ?>
  53. </body></html>
  54. <?php
  55. exit;
  56. }
  57. if (count($options) == 0 || isset($options["help"]) ) {
  58. print "Tiny Tiny RSS data update script.\n\n";
  59. print "Options:\n";
  60. print " --feeds - update feeds\n";
  61. print " --feedbrowser - update feedbrowser\n";
  62. print " --daemon - start single-process update daemon\n";
  63. print " --task N - create lockfile using this task id\n";
  64. print " --cleanup-tags - perform tags table maintenance\n";
  65. print " --quiet - don't output messages to stdout\n";
  66. print " --log FILE - log messages to FILE\n";
  67. print " --indexes - recreate missing schema indexes\n";
  68. print " --update-schema - update database schema\n";
  69. print " --convert-filters - convert type1 filters to type2\n";
  70. print " --force-update - force update of all feeds\n";
  71. print " --list-plugins - list all available plugins\n";
  72. print " --help - show this help\n";
  73. print "Plugin options:\n";
  74. foreach (PluginHost::getInstance()->get_commands() as $command => $data) {
  75. $args = $data['arghelp'];
  76. printf(" --%-19s - %s\n", "$command $args", $data["description"]);
  77. }
  78. return;
  79. }
  80. if (!isset($options['daemon'])) {
  81. require_once "errorhandler.php";
  82. }
  83. if (!isset($options['update-schema'])) {
  84. $schema_version = get_schema_version();
  85. if ($schema_version != SCHEMA_VERSION) {
  86. die("Schema version is wrong, please upgrade the database.\n");
  87. }
  88. }
  89. define('QUIET', isset($options['quiet']));
  90. if (isset($options["log"])) {
  91. _debug("Logging to " . $options["log"]);
  92. define('LOGFILE', $options["log"]);
  93. }
  94. if (!isset($options["daemon"])) {
  95. $lock_filename = "update.lock";
  96. } else {
  97. $lock_filename = "update_daemon.lock";
  98. }
  99. if (isset($options["task"])) {
  100. _debug("Using task id " . $options["task"]);
  101. $lock_filename = $lock_filename . "-task_" . $options["task"];
  102. }
  103. if (isset($options["pidlock"])) {
  104. $my_pid = $options["pidlock"];
  105. $lock_filename = "update_daemon-$my_pid.lock";
  106. }
  107. _debug("Lock: $lock_filename");
  108. $lock_handle = make_lockfile($lock_filename);
  109. $must_exit = false;
  110. if (isset($options["task"]) && isset($options["pidlock"])) {
  111. $waits = $options["task"] * 5;
  112. _debug("Waiting before update ($waits)");
  113. sleep($waits);
  114. }
  115. // Try to lock a file in order to avoid concurrent update.
  116. if (!$lock_handle) {
  117. die("error: Can't create lockfile ($lock_filename). ".
  118. "Maybe another update process is already running.\n");
  119. }
  120. if (isset($options["force-update"])) {
  121. _debug("marking all feeds as needing update...");
  122. db_query( "UPDATE ttrss_feeds SET last_update_started = '1970-01-01',
  123. last_updated = '1970-01-01'");
  124. }
  125. if (isset($options["feeds"])) {
  126. update_daemon_common();
  127. housekeeping_common(true);
  128. PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK, "hook_update_task", $op);
  129. }
  130. if (isset($options["feedbrowser"])) {
  131. $count = update_feedbrowser_cache();
  132. print "Finished, $count feeds processed.\n";
  133. }
  134. if (isset($options["daemon"])) {
  135. while (true) {
  136. $quiet = (isset($options["quiet"])) ? "--quiet" : "";
  137. $log = isset($options['log']) ? '--log '.$options['log'] : '';
  138. passthru(PHP_EXECUTABLE . " " . $argv[0] ." --daemon-loop $quiet $log");
  139. _debug("Sleeping for " . DAEMON_SLEEP_INTERVAL . " seconds...");
  140. sleep(DAEMON_SLEEP_INTERVAL);
  141. }
  142. }
  143. if (isset($options["daemon-loop"])) {
  144. if (!make_stampfile('update_daemon.stamp')) {
  145. _debug("warning: unable to create stampfile\n");
  146. }
  147. update_daemon_common(isset($options["pidlock"]) ? 50 : DAEMON_FEED_LIMIT);
  148. if (!isset($options["pidlock"]) || $options["task"] == 0)
  149. housekeeping_common(true);
  150. PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK, "hook_update_task", $op);
  151. }
  152. if (isset($options["cleanup-tags"])) {
  153. $rc = cleanup_tags( 14, 50000);
  154. _debug("$rc tags deleted.\n");
  155. }
  156. if (isset($options["indexes"])) {
  157. _debug("PLEASE BACKUP YOUR DATABASE BEFORE PROCEEDING!");
  158. _debug("Type 'yes' to continue.");
  159. if (read_stdin() != 'yes')
  160. exit;
  161. _debug("clearing existing indexes...");
  162. if (DB_TYPE == "pgsql") {
  163. $result = db_query( "SELECT relname FROM
  164. pg_catalog.pg_class WHERE relname LIKE 'ttrss_%'
  165. AND relname NOT LIKE '%_pkey'
  166. AND relkind = 'i'");
  167. } else {
  168. $result = db_query( "SELECT index_name,table_name FROM
  169. information_schema.statistics WHERE index_name LIKE 'ttrss_%'");
  170. }
  171. while ($line = db_fetch_assoc($result)) {
  172. if (DB_TYPE == "pgsql") {
  173. $statement = "DROP INDEX " . $line["relname"];
  174. _debug($statement);
  175. } else {
  176. $statement = "ALTER TABLE ".
  177. $line['table_name']." DROP INDEX ".$line['index_name'];
  178. _debug($statement);
  179. }
  180. db_query( $statement, false);
  181. }
  182. _debug("reading indexes from schema for: " . DB_TYPE);
  183. $fp = fopen("schema/ttrss_schema_" . DB_TYPE . ".sql", "r");
  184. if ($fp) {
  185. while ($line = fgets($fp)) {
  186. $matches = array();
  187. if (preg_match("/^create index ([^ ]+) on ([^ ]+)$/i", $line, $matches)) {
  188. $index = $matches[1];
  189. $table = $matches[2];
  190. $statement = "CREATE INDEX $index ON $table";
  191. _debug($statement);
  192. db_query( $statement);
  193. }
  194. }
  195. fclose($fp);
  196. } else {
  197. _debug("unable to open schema file.");
  198. }
  199. _debug("all done.");
  200. }
  201. if (isset($options["convert-filters"])) {
  202. _debug("WARNING: this will remove all existing type2 filters.");
  203. _debug("Type 'yes' to continue.");
  204. if (read_stdin() != 'yes')
  205. exit;
  206. _debug("converting filters...");
  207. db_query( "DELETE FROM ttrss_filters2");
  208. $result = db_query( "SELECT * FROM ttrss_filters ORDER BY id");
  209. while ($line = db_fetch_assoc($result)) {
  210. $owner_uid = $line["owner_uid"];
  211. // date filters are removed
  212. if ($line["filter_type"] != 5) {
  213. $filter = array();
  214. if (sql_bool_to_bool($line["cat_filter"])) {
  215. $feed_id = "CAT:" . (int)$line["cat_id"];
  216. } else {
  217. $feed_id = (int)$line["feed_id"];
  218. }
  219. $filter["enabled"] = $line["enabled"] ? "on" : "off";
  220. $filter["rule"] = array(
  221. json_encode(array(
  222. "reg_exp" => $line["reg_exp"],
  223. "feed_id" => $feed_id,
  224. "filter_type" => $line["filter_type"])));
  225. $filter["action"] = array(
  226. json_encode(array(
  227. "action_id" => $line["action_id"],
  228. "action_param_label" => $line["action_param"],
  229. "action_param" => $line["action_param"])));
  230. // Oh god it's full of hacks
  231. $_REQUEST = $filter;
  232. $_SESSION["uid"] = $owner_uid;
  233. $filters = new Pref_Filters($_REQUEST);
  234. $filters->add();
  235. }
  236. }
  237. }
  238. if (isset($options["update-schema"])) {
  239. _debug("checking for updates (" . DB_TYPE . ")...");
  240. $updater = new DbUpdater(Db::get(), DB_TYPE, SCHEMA_VERSION);
  241. if ($updater->isUpdateRequired()) {
  242. _debug("schema update required, version " . $updater->getSchemaVersion() . " to " . SCHEMA_VERSION);
  243. _debug("WARNING: please backup your database before continuing.");
  244. _debug("Type 'yes' to continue.");
  245. if (read_stdin() != 'yes')
  246. exit;
  247. for ($i = $updater->getSchemaVersion() + 1; $i <= SCHEMA_VERSION; $i++) {
  248. _debug("performing update up to version $i...");
  249. $result = $updater->performUpdateTo($i);
  250. _debug($result ? "OK!" : "FAILED!");
  251. if (!$result) return;
  252. }
  253. } else {
  254. _debug("update not required.");
  255. }
  256. }
  257. if (isset($options["list-plugins"])) {
  258. $tmppluginhost = new PluginHost();
  259. $tmppluginhost->load_all($tmppluginhost::KIND_ALL);
  260. $enabled = array_map("trim", explode(",", PLUGINS));
  261. echo "List of all available plugins:\n";
  262. foreach ($tmppluginhost->get_plugins() as $name => $plugin) {
  263. $about = $plugin->about();
  264. $status = $about[3] ? "system" : "user";
  265. if (in_array($name, $enabled)) $name .= "*";
  266. printf("%-50s %-10s v%.2f (by %s)\n%s\n\n",
  267. $name, $status, $about[0], $about[2], $about[1]);
  268. }
  269. echo "Plugins marked by * are currently enabled for all users.\n";
  270. }
  271. PluginHost::getInstance()->run_commands($options);
  272. if (file_exists(LOCK_DIRECTORY . "/$lock_filename"))
  273. unlink(LOCK_DIRECTORY . "/$lock_filename");
  274. ?>