Add feature to "hide" users on specific filters for N time

main alpha-v1.0.5
Bofh 2022-12-13 16:37:48 +01:00
parent dcc159ea91
commit df6a94fa11
6 changed files with 91 additions and 10 deletions

3
api/v1/cache/put/index.php vendored 100644
View File

@ -0,0 +1,3 @@
<?php chdir('../../../../') ?>
<?php require 'base.php' ?>
<?php mod_php() ?>

30
api/v1/cache/put/mod.php vendored 100644
View File

@ -0,0 +1,30 @@
<?php
$_ = function() {
if (!isset($_GET['keys']))
return apiresult(['error' => '<key> parameter was not provided'], 400);
if (!isset($_GET['content']))
return apiresult(['error' => '<content> parameter was not provided'], 400);
$expires = 3600;
if (isset($_GET['expires']))
$expires = intval($_GET['expires']);
$keys = explode(';', trim($_GET['keys']));
$content = trim($_GET['content']);
$nkeys = [];
foreach ($keys as $key) {
$key = trim($key);
if (strpos($key, 'hash:') === 0)
$key = md5(trim(substr($key, strpos($key, 'hash:')+5)));
$key = _cachekey($key);
$nkeys [] = $key;
}
$key = implode(',', $nkeys);
$result = content_cache__put($key, 'ondemand,'.$expires, $content);
$realkey = md5($key).',ondemand,'.$expires;
if (gettype($result) === 'integer')
return apiresult(['ok' => 'Cached content created with key: '.$key, 'data' => $realkey]);
return apiresult(['error' => 'Unknown error when creating the cache key: '.$key], 500);
};
$_();

View File

@ -22,10 +22,13 @@ if (isset($_GET['filter_id'])) {
$_GET['type'] = 'users';
$_GET = mod_php('api/v1/config/filters/get');
$_GET['instance'] = $GLOBALS['ap_instance'];
unset($_GET['preset_name']);
unset($_GET['id']);
}
//////////
// used to identify this filter as unique (not using the "filter_id", as is not set by the weh UI)
// KEY: $software.$instance.$preset_name
$filter_key = md5($GLOBALS['ap_software'].$GLOBALS['ap_instance'].trim($_GET['preset_name']));
$filtered_accounts = [];
$filtered_accounts_index = [];
@ -218,6 +221,10 @@ foreach ($filtered_accounts as $id) {
in_array($id, $suspended_users))
continue;
$ckey = _cachekey_construct('temp_hidden', $filter_key, $acct_for_trusted);
if (content_cache__exists($ckey) !== false)
continue;
$following = $pg->fetch('SELECT count(1) FROM follows WHERE account_id = \''.$id.'\'');
$followers = $pg->fetch('SELECT count(1) FROM follows WHERE target_account_id = \''.$id.'\'');
if (isset($_GET['no_follows']) && (intval($following['count']) > 0 || intval($followers['count']) > 0))

View File

@ -480,6 +480,17 @@ function matches_comparing_expression($expr, $text) {
return in_array($result, [0,false]) ? false : true;
}
function _cachekey_construct(...$keys) {
$nkeys = [];
foreach ($keys as $key)
$nkeys []= _cachekey($key);
return implode(',', $nkeys);
}
function _cachekey($str) {
return preg_replace('/[^a-z0-9\_]+/', '', strtolower($str));
}
function content_cache__exists($key) {
$cache_dir = $GLOBALS['appconf']['data_dir'].'/cache';
if (!file_exists($cache_dir)) {
@ -527,7 +538,7 @@ function content_cache__put($key, $config, $data) {
$cache_file .= ','.$ps[0];
else if ($ps[0] === 'ondemand')
$cache_file .= ','.$config;
file_put_contents($cache_file, serialize($data));
return file_put_contents($cache_file, serialize($data));
}
function cronjob_db_create__check_cachecfg($software, $instance, $sql, $cache=null) {

View File

@ -171,12 +171,17 @@
<div class="only mastodon disable-able">{mastodon:fields}</div>
<div class="note">{note}</div>
<div style="margin-top: 1em; text-align: right;">
<button onclick="if (window.view.instance.do.users.trust_user('{acct}'))
<button style="float:left" onclick="if ({do.js}.users.trust_user('{acct}'))
E.element('.item[data-id=&quot;{id}&quot;]').remove()"
class="btn mid green"><i class="fa fa-thumbs-up fa-fw"></i>Trust</button>
<button onclick="if ({do.js}.users.hide_on_filters('{acct}', 86400))
E.element('.item[data-id=&quot;{id}&quot;]').remove()"
class="btn mid"><i class="fa fa-clock-o fa-fw"></i>Hide 1 day</button>
<button onclick="
if ('' === '{disabledClass}') {
if (window.view.instance.do.users.silence('{id}')) {
if ({do.js}.users.silence('{id}')) {
E.element('.item[data-id=&quot;{id}&quot;]').classList.add('silenced');
this.querySelector('span').innerText = 'Silenced';
this.setAttribute('disabled', 'true');
@ -184,7 +189,8 @@
}"
class="btn mid disable-able" {disabledHTML}>
<i class="fa fa-volume-mute fa-fw"></i><span>{silencedText}</span></button>
<button onclick="if (window.view.instance.do.users.suspend('{id}')) {
<button onclick="if ({do.js}.users.suspend('{id}')) {
E.element('.item[data-id=&quot;{id}&quot;]').classList.add('suspended');
this.querySelector('span'),innerText = 'Suspended'}"
class="btn mid red"><i class="fa fa-ban fa-fw"></i><span>Suspend</span></button>

View File

@ -18,14 +18,20 @@ window.view.instance = {
show_config: function() {
window.location.hash = window.location.hash.replace('#instance/','#instance_config/');
},
acct_fill: function(acct) {
if (!acct.includes('@')) {
const hargs = get_hash_arguments();
return acct+'@'+hargs.instance;
}
return acct;
},
do: {
users: {
trust_user: function(acct) {
if (!acct.includes('@')) {
const hargs = get_hash_arguments();
acct = acct+'@'+hargs.instance;
}
if (!confirm('Are you sure you want to trust this user? It will NOT appear in any <filter results/timeline or screen> in all this web application!')) return false;
acct = window.view.instance.acct_fill(acct);
if (!confirm('Are you sure you want to trust this user? It will NOT appear in any '+
'<filter results/timeline or screen> in all this web application!')) return false;
http.get(`api/v1/config/trusted_users/add?acct=${acct}`,
{}, function(js) {
if (js.ok) return toast.info(js.ok);
@ -33,9 +39,25 @@ window.view.instance = {
});
return true;
},
hide_on_filters: function(acct, expires) {
const pname = window.view.instance.do.filter_users.get_current_filter().preset_name;
if (pname === undefined) return false;
const hargs = get_hash_arguments();
acct = window.view.instance.acct_fill(acct);
http.get(`api/v1/cache/put?keys=temp_hidden;`+
`hash:${hargs.software}${hargs.instance}${pname}; ${acct}`+
`&content=temp_hidden&expires=${expires}`,
{}, function(js) {
if (js.ok) return toast.info('User has been hidden from this filter for the specified time.');
});
return true;
},
suspend: function(_id) {
if (!confirm('Are you sure you want to suspend this user?')) return false;
const hargs = get_hash_arguments();
http.get(`api/v1/http/mastodon/accounts/suspend?instance=${hargs.instance}&id=${_id}`,
{}, function(js) {
toast.info('User has been successfully suspended');
@ -44,6 +66,7 @@ window.view.instance = {
},
silence: function(_id) {
const hargs = get_hash_arguments();
http.get(`api/v1/http/mastodon/accounts/silence?instance=${hargs.instance}&id=${_id}`,
{}, function(js) {
toast.info('User has been successfully silenced');
@ -328,6 +351,7 @@ window.view.instance = {
const hargs = get_hash_arguments();
E.http_template('instance/filter-users', function(html) {
html = html.replaceAll('{view.js}', 'window.view.instance.do.filter_users');
html = html.replaceAll('{do.js}', 'window.view.instance.do');
E.element('#window-instance #container').innerHTML = html;
E.elemid('profile-search-type-simple').onchange = function(e) {
if (e.target.checked) {