This commit is contained in:
pezcurrel 2022-12-18 09:35:04 +01:00
parent f269bb901d
commit 690b54521b

195
web/clitools/searchdupes.php Executable file
View file

@ -0,0 +1,195 @@
#!/usr/bin/php
<?php
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
define('N',"\n");
define('SNAME',basename(__FILE__));
define('CONFIGFP',__DIR__.'/../../conf/mustard.ini');
$help='SYNOPSYS
'.SNAME.' [options]
DESCRIPTION
This is a script to check the «Instances» table of mastostart database for
multiple records with the same URI value.
OPTIONS
-d, --delete
For each URI with multiple records, give the possibility to interactively
choose which record to keep, and delete the others (default); or to
automatically keep the record with the lowest ID and delete the others
(see below).
-I, --nonint
Disable interactive mode.
-h, --help
Show this help text and exit.'.N;
$opts=[
'delete'=>false,
'interactive'=>true
];
for ($i=1; $i<$argc; $i++) {
if ($argv[$i]=='-h' || $argv[$i]=='--help') {
mexit($help,0);
} elseif ($argv[$i]=='-d' || $argv[$i]=='--delete') {
$opts['delete']=true;
} elseif ($argv[$i]=='-I' || $argv[$i]=='--nonint') {
$opts['interactive']=false;
} else {
mexit('Dont know how to interpret «'.$argv[$i].'», please read the help text using «-h» or «--help» option.'.N,1);
}
}
use function mysqli_real_escape_string as myesc;
function mexit($msg,$code) {
global $link;
if (isset($link)) mysqli_close($link);
if ($code>0)
fwrite(STDERR,$msg);
else
echo($msg);
exit($code);
}
$iniarr=@parse_ini_file(CONFIGFP)
or mexit('Could not open config file «'.CONFIGFP.'».'.N,1);
try { $link=mysqli_connect($iniarr['db_host'],$iniarr['db_admin_name'],$iniarr['db_admin_password'],$iniarr['db_name'],$iniarr['db_port'],$iniarr['db_socket']); }
catch (Exception $error) { mexit('Could not connect to mysql server: '.$error->getMessage().' (error code: '.$error->getCode().').'.N,1); }
mysqli_set_charset($link,'utf8mb4');
function myq(&$l,$q) {
try {
$res=mysqli_query($l,$q);
}
catch (Exception $e) {
echo('query «'.$q.'» failed: '.$e->getMessage().' (error code: '.$e->getCode().').'.N);
exit(3);
}
return($res);
}
$insts=[];
$res=mysqli_query($link,'SELECT * FROM Instances');
while ($row=mysqli_fetch_assoc($res))
$insts[$row['URI']][]=$row;
//ID: 83; FirstSeen: 1602617889; IsMastodon: 0; Dead: 0; New: 0; Good: 0; Chosen: 0; Priority: NULL; Visible: 0; Noxious: 0; NoxReason: NULL; NoxLastModTS: NULL; URI: ambrosia.cafe; Title: ambrosia café; ShortDesc: NULL; LongDesc: Pleroma: An efficient and flexible fediverse server; OurDesc: NULL; OurDescEN: NULL; LocalityID: NULL; OurLangsLock: 0; Email: admin@ambrosia.cafe; Software: NULL; Version: 2.7.2 (compatible; Pleroma 2.4.2); UserCount: 3; StatusCount: 299; DomainCount: 2900; ActiveUsersMonth: NULL; ActiveUsersHalfYear: NULL; Thumb: https://ambrosia.cafe/instance/thumbnail.jpeg; RegOpen: 0; RegReqApproval: 0; MaxTootChars: 5000; AdmAccount: NULL; AdmDisplayName: NULL; AdmCreatedAt: NULL; AdmNote: NULL; AdmURL: NULL; AdmAvatar: NULL; AdmHeader: NULL; LastCheckOk: 0; GuestID: NULL; LastGuestEdit: NULL; InsertTS: NULL; RPos: 4291;
$tot=0;
foreach ($insts as $uri=>$rows)
if (count($rows)>1) $tot++;
if ($tot>0 && $opts['delete']) {
$i=0;
foreach ($insts as $uri=>$rows) {
$cr=count($rows);
if ($cr>1) {
$i++;
echo('<<< '.$i.'/'.$tot.': '.$uri.' ('.$cr.' records) >>>'.N.N);
$buff=[];
foreach ($rows as $row) {
$row['FirstSeen']=utstd($row['FirstSeen']);
$row['NoxLastModTS']=utstd($row['NoxLastModTS']);
$row['AdmCreatedAt']=utstd($row['AdmCreatedAt']);
$row['LastGuestEdit']=utstd($row['LastGuestEdit']);
$row['InsertTS']=utstd($row['InsertTS']);
$out='';
foreach ($row as $key=>$val)
$out.=$key.': '.pr($val).'; ';
$out=substr($out,0,-2);
//echo($out.N.N);
$buff[$row['ID']]=['id'=>$row['ID'],'row'=>$out];
}
asort($buff);
$ii=0;
$recs=[];
foreach ($buff as $rec) {
$ii++;
$recs[$ii]=$rec;
echo($ii.': '.$rec['row'].N.N);
}
if ($opts['interactive']) {
$ans=[];
for ($iii=1; $iii<=$ii; $iii++)
$ans[]=$iii;
$ans[]='e';
$inp=null;
while (!in_array($inp,$ans)) {
echo('Which one do you want to keep? ['.implode('/',$ans).'] ');
$inp=strtolower(trim(fgets(STDIN)));
}
} else {
$inp=1;
}
if ($inp=='e') {
mexit('Ok, bye :-)'.N,0);
} else {
$inp+=0;
echo(N.'Ok, ill keep the record with ID='.$recs[$inp]['id'].N);
foreach ($recs as $key=>$rec) {
if ($key!=$inp) {
echo('Deleting record with ID='.$rec['id'].' ...'.N);
myq($link,'DELETE FROM Instances WHERE ID='.$rec['id']);
echo('Deleted '.mysqli_affected_rows($link).' records from Instances table.'.N);
myq($link,'DELETE FROM InstActivity WHERE InstID='.$rec['id']);
echo('Deleted '.mysqli_affected_rows($link).' records from InstActivity table.'.N);
myq($link,'DELETE FROM InstChecks WHERE InstID='.$rec['id']);
echo('Deleted '.mysqli_affected_rows($link).' records from InstChecks table.'.N);
myq($link,'DELETE FROM InstFinancing WHERE InstID='.$rec['id']);
echo('Deleted '.mysqli_affected_rows($link).' records from InstFinancing table.'.N);
myq($link,'DELETE FROM InstLangs WHERE InstID='.$rec['id']);
echo('Deleted '.mysqli_affected_rows($link).' records from InstLangs table.'.N);
myq($link,'DELETE FROM InstOurLangs WHERE InstID='.$rec['id']);
echo('Deleted '.mysqli_affected_rows($link).' records from InstOurLangs table.'.N);
myq($link,'DELETE FROM InstPolicies WHERE InstID='.$rec['id']);
echo('Deleted '.mysqli_affected_rows($link).' records from InstPolicies table.'.N);
myq($link,'DELETE FROM InstTags WHERE InstID='.$rec['id']);
echo('Deleted '.mysqli_affected_rows($link).' records from InstTags table.'.N);
myq($link,'DELETE FROM InstTrends WHERE InstID='.$rec['id']);
echo('Deleted '.mysqli_affected_rows($link).' records from InstTrends table.'.N);
$users=myq($link,'SELECT ID FROM Users WHERE InstID='.$rec['id']);
$iii=0;
while ($user=mysqli_fetch_assoc($users)) {
myq($link,'DELETE FROM UsersFields WHERE UserID='.$user['ID']);
$iii+=mysqli_affected_rows($link);
}
echo('Deleted '.$iii.' records from UsersFields table.'.N);
myq($link,'DELETE FROM Users WHERE InstID='.$rec['id']);
echo('Deleted '.mysqli_affected_rows($link).' records from Users table.'.N);
}
}
echo(N);
}
}
}
}
echo('Total dupes: '.$tot.N);
mysqli_close($link);
exit(0);
function utstd($val) {
if (is_null($val)) return(null);
$val=round($val);
return(date('Y-m-d H:i:s',$val));
}
function pr($val) {
if (is_null($val)) return('NULL');
return($val);
}
?>