From 117efb6fa497ce873c9e18368d2a9fc61eaa8ef8 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Mon, 19 Jan 2015 12:52:15 +0300 Subject: [PATCH] add trgm plugin for postgresql --- plugins/af_psql_trgm/init.php | 202 ++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 plugins/af_psql_trgm/init.php diff --git a/plugins/af_psql_trgm/init.php b/plugins/af_psql_trgm/init.php new file mode 100644 index 00000000..a1ee040e --- /dev/null +++ b/plugins/af_psql_trgm/init.php @@ -0,0 +1,202 @@ + 1) $similarity = 1; + + if ($min_title_length < 0) $min_title_length = 0; + + $similarity = sprintf("%.2f", $similarity); + + $this->host->set($this, "similarity", $similarity); + $this->host->set($this, "min_title_length", $min_title_length); + + echo T_sprintf("Data saved (%s)", $similarity); + } + + function init($host) { + $this->host = $host; + + $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); + $host->add_hook($host::HOOK_PREFS_TAB, $this); + $host->add_hook($host::HOOK_PREFS_EDIT_FEED, $this); + $host->add_hook($host::HOOK_PREFS_SAVE_FEED, $this); + + } + + function hook_prefs_tab($args) { + if ($args != "prefFeeds") return; + + print "
"; + + if (DB_TYPE != "pgsql") { + print_error("Database type not supported."); + } + + $result = db_query("select 'similarity'::regproc"); + + if (db_num_rows($result) == 0) { + print_error("pg_trgm extension not found."); + } + + $similarity = $this->host->get($this, "similarity"); + $min_title_length = $this->host->get($this, "min_title_length"); + + if (!$similarity) $similarity = '0.75'; + if (!$min_title_length) $min_title_length = '32'; + + print "
"; + + print ""; + + print ""; + print ""; + print ""; + + print_notice("PostgreSQL trigram extension returns string similarity as a floating point number (0-1). Setting it too low might produce false positives, zero disables checking."); + + print "
"; + print_notice("Only data in other feeds is checked, i.e. sequential duplicate posts in one feed will not be detected by this plugin."); + + print "
"; + print_notice("Enable the plugin for specific feeds in the feed editor."); + + print "

" . __("Global settings") . "

"; + + print ""; + + print ""; + print ""; + print ""; + print ""; + + + print "
".__("Minimum similarity:")." +
".__("Minimum title length:")." +
"; + + print "

"; + + print "

"; + + print "
"; + } + + //PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_EDIT_FEED, + // "hook_prefs_edit_feed", $feed_id); + // PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_SAVE_FEED, + // "hook_prefs_save_feed", $feed_id); + + function hook_prefs_edit_feed($feed_id) { + print "
".__("Similarity (pg_trgm)")."
"; + print "
"; + + $enabled_feeds = $this->host->get($this, "enabled_feeds"); + if (!array($enabled_feeds)) $enabled_feeds = array(); + + $key = array_search($feed_id, $enabled_feeds); + $checked = $key !== FALSE ? "checked" : ""; + + print "
 "; + + print "
"; + } + + function hook_prefs_save_feed($feed_id) { + $enabled_feeds = $this->host->get($this, "enabled_feeds"); + if (!is_array($enabled_feeds)) $enabled_feeds = array(); + + $enable = checkbox_to_sql_bool($_POST["trgm_similarity_enabled"]) == 'true'; + $key = array_search($feed_id, $enabled_feeds); + + if ($enable) { + if ($key === FALSE) { + array_push($enabled_feeds, $feed_id); + } + } else { + if ($key !== FALSE) { + unset($enabled_feeds[$key]); + } + } + + $this->host->set($this, "enabled_feeds", $enabled_feeds); + } + + function hook_article_filter($article) { + + if (DB_TYPE != "pgsql") return $article; + + $result = db_query("select 'similarity'::regproc"); + if (db_num_rows($result) == 0) return $article; + + $enabled_feeds = $this->host->get($this, "enabled_feeds"); + $key = array_search($article["feed"]["id"], $enabled_feeds); + if ($key === FALSE) return $article; + + $similarity = (float) $this->host->get($this, "similarity"); + if ($similarity < 0.01) return $article; + + $min_title_length = (int) $this->host->get($this, "min_length"); + if (mb_strlen($article["title"]) < $min_title_length) return $article; + + $owner_uid = $article["owner_uid"]; + $feed_id = $article["feed"]["id"]; + + $title_escaped = db_escape_string($article["title"]); + + $result = db_query("SELECT MAX(SIMILARITY(title, '$title_escaped')) AS ms + FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id AND + date_entered >= NOW() - interval '1 day' AND + feed_id != $feed_id AND + owner_uid = $owner_uid"); + + $similarity_result = db_fetch_result($result, 0, "ms"); + + //_debug("similarity result: $similarity_result"); + + if ($similarity_result >= $similarity) { + $article["force_catchup"] = true; + } + + return $article; + + } + + function api_version() { + return 2; + } + +} +?> -- 2.39.5