2023-11-21 00:36:52 +00:00
< ? php
namespace Appwrite\Platform\Tasks ;
use League\Csv\CannotInsertRecord ;
2024-03-06 17:34:21 +00:00
use League\Csv\Writer ;
use PHPMailer\PHPMailer\PHPMailer ;
2023-11-21 00:36:52 +00:00
use Utopia\App ;
use Utopia\Cache\Cache ;
use Utopia\CLI\Console ;
use Utopia\Database\Database ;
use Utopia\Database\Query ;
2024-03-06 17:34:21 +00:00
use Utopia\Platform\Action ;
2023-11-21 00:36:52 +00:00
use Utopia\Pools\Group ;
use Utopia\Registry\Registry ;
2024-04-01 11:02:47 +00:00
use Utopia\System\System ;
2023-11-21 00:36:52 +00:00
class GetMigrationStats extends Action
{
/*
* Csv cols headers
*/
private array $columns = [
'Project ID' ,
'$id' ,
'$createdAt' ,
'status' ,
'stage' ,
'source'
];
protected string $directory = '/usr/local' ;
protected string $path ;
protected string $date ;
public static function getName () : string
{
return 'get-migration-stats' ;
}
public function __construct ()
{
$this
-> desc ( 'Get stats for projects' )
-> inject ( 'pools' )
-> inject ( 'cache' )
-> inject ( 'dbForConsole' )
-> inject ( 'register' )
-> callback ( function ( Group $pools , Cache $cache , Database $dbForConsole , Registry $register ) {
$this -> action ( $pools , $cache , $dbForConsole , $register );
});
}
/**
* @ throws \Utopia\Exception
* @ throws CannotInsertRecord
*/
public function action ( Group $pools , Cache $cache , Database $dbForConsole , Registry $register ) : void
{
//docker compose exec -t appwrite get-migration-stats
Console :: title ( 'Migration stats calculation V1' );
Console :: success ( APP_NAME . ' Migration stats calculation has started' );
/* Initialise new Utopia app */
$app = new App ( 'UTC' );
$console = $app -> getResource ( 'console' );
/** CSV stuff */
$this -> date = date ( 'Y-m-d' );
$this -> path = " { $this -> directory } /migration_stats_ { $this -> date } .csv " ;
$csv = Writer :: createFromPath ( $this -> path , 'w' );
$csv -> insertOne ( $this -> columns );
/** Database connections */
$totalProjects = $dbForConsole -> count ( 'projects' );
Console :: success ( " Found a total of: { $totalProjects } projects " );
$projects = [ $console ];
$count = 0 ;
2023-11-21 00:39:07 +00:00
$limit = 100 ;
$sum = 100 ;
2023-11-21 00:36:52 +00:00
$offset = 0 ;
while ( ! empty ( $projects )) {
foreach ( $projects as $project ) {
/**
* Skip user projects with id 'console'
*/
if ( $project -> getId () === 'console' ) {
continue ;
}
Console :: info ( " Getting stats for { $project -> getId () } " );
try {
$db = $project -> getAttribute ( 'database' );
$adapter = $pools
-> get ( $db )
-> pop ()
-> getResource ();
$dbForProject = new Database ( $adapter , $cache );
$dbForProject -> setDefaultDatabase ( 'appwrite' );
$dbForProject -> setNamespace ( '_' . $project -> getInternalId ());
/** Get Project ID */
$stats [ 'Project ID' ] = $project -> getId ();
/** Get Migration details */
$migrations = $dbForProject -> find ( 'migrations' , [
Query :: limit ( 500 )
]);
$migrations = array_map ( function ( $migration ) use ( $project ) {
2023-11-21 01:10:56 +00:00
return [
$project -> getId (),
$migration -> getAttribute ( '$id' ),
$migration -> getAttribute ( '$createdAt' ),
$migration -> getAttribute ( 'status' ),
$migration -> getAttribute ( 'stage' ),
$migration -> getAttribute ( 'source' ),
];
2023-11-21 00:36:52 +00:00
}, $migrations );
2023-11-21 01:10:24 +00:00
if ( ! empty ( $migrations )) {
2023-11-21 00:39:07 +00:00
$csv -> insertAll ( $migrations );
}
2023-11-21 00:36:52 +00:00
} catch ( \Throwable $th ) {
Console :: error ( 'Failed on project ("' . $project -> getId () . '") with error on File: ' . $th -> getFile () . ' line no: ' . $th -> getline () . ' with message: ' . $th -> getMessage ());
} finally {
$pools
-> get ( $db )
-> reclaim ();
}
}
$sum = \count ( $projects );
$projects = $dbForConsole -> find ( 'projects' , [
Query :: limit ( $limit ),
Query :: offset ( $offset ),
]);
$offset = $offset + $limit ;
$count = $count + $sum ;
}
Console :: log ( 'Iterated through ' . $count - 1 . '/' . $totalProjects . ' projects...' );
$pools
-> get ( 'console' )
-> reclaim ();
/** @var PHPMailer $mail */
$mail = $register -> get ( 'smtp' );
$mail -> clearAddresses ();
$mail -> clearAllRecipients ();
$mail -> clearReplyTos ();
$mail -> clearAttachments ();
$mail -> clearBCCs ();
$mail -> clearCCs ();
try {
/** Addresses */
2024-04-01 11:02:47 +00:00
$mail -> setFrom ( System :: getEnv ( '_APP_SYSTEM_EMAIL_ADDRESS' , APP_EMAIL_TEAM ), 'Appwrite Cloud Hamster' );
$recipients = explode ( ',' , System :: getEnv ( '_APP_USERS_STATS_RECIPIENTS' , '' ));
2023-11-21 00:36:52 +00:00
foreach ( $recipients as $recipient ) {
$mail -> addAddress ( $recipient );
}
/** Attachments */
$mail -> addAttachment ( $this -> path );
/** Content */
$mail -> Subject = " Migration Report for { $this -> date } " ;
$mail -> Body = " Please find the migration report atttached " ;
$mail -> send ();
Console :: success ( 'Email has been sent!' );
2024-02-08 01:17:54 +00:00
} catch ( \Throwable $e ) {
2023-11-21 00:36:52 +00:00
Console :: error ( " Message could not be sent. Mailer Error: { $mail -> ErrorInfo } " );
}
}
}