Recursive session search

This commit is contained in:
Alexander Pankratov 2020-03-28 13:44:14 +03:00
parent ca740abbbd
commit e296836df5
6 changed files with 79 additions and 59 deletions

View File

@ -1,5 +1,6 @@
<?php
use TelegramApiServer\Files;
use TelegramApiServer\Migrations\SessionsMigration;
use TelegramApiServer\Migrations\SwooleToAmpMigration;
@ -68,10 +69,10 @@ foreach ($options['session'] as $session) {
throw new InvalidArgumentException('Session name specified as directory');
}
$session = TelegramApiServer\Client::getSessionFile($session);
$session = Files::getSessionFile($session);
if (preg_match('~[' . preg_quote('*?[]!', '~') . ']~', $session)) {
$sessions = glob($session);
$sessions = Files::globRecursive($session);
} else {
$sessions[] = $session;
}

View File

@ -14,53 +14,9 @@ use function Amp\call;
class Client
{
public static string $sessionExtension = '.madeline';
public static string $sessionFolder = 'sessions';
/** @var MadelineProto\API[] */
public array $instances = [];
/**
* @param string|null $session
*
* @return string|null
*/
public static function getSessionFile(?string $session): ?string
{
if (!$session) {
return null;
}
$session = trim(trim($session), '/');
$session = static::$sessionFolder . '/' . $session . static::$sessionExtension;
$session = str_replace('//', '/', $session);
return $session;
}
public static function getSessionName(?string $sessionFile): ?string
{
if (!$sessionFile) {
return null;
}
preg_match(
'~' . static::$sessionFolder . "/(?'sessionName'.*?)" . static::$sessionExtension . '$~',
$sessionFile,
$matches
);
return $matches['sessionName'] ?? null;
}
public static function checkOrCreateSessionFolder(string $session): void
{
$directory = dirname($session);
if ($directory && $directory !== '.' && !is_dir($directory)) {
$parentDirectoryPermissions = fileperms(ROOT_DIR);
if (!mkdir($directory, $parentDirectoryPermissions, true) && !is_dir($directory)) {
throw new RuntimeException(sprintf('Directory "%s" was not created', $directory));
}
}
}
private static function isSessionLoggedIn(MadelineProto\API $instance): bool
{
return ($instance->API->authorized ?? MTProto::NOT_LOGGED_IN) === MTProto::LOGGED_IN;
@ -71,7 +27,7 @@ class Client
warning(PHP_EOL . 'Starting MadelineProto...' . PHP_EOL);
foreach ($sessionFiles as $file) {
$sessionName = static::getSessionName($file);
$sessionName = Files::getSessionName($file);
$instance = $this->addSession($sessionName);
$this->runSession($instance);
}
@ -90,8 +46,8 @@ class Client
if (isset($this->instances[$session])) {
throw new InvalidArgumentException('Session already exists');
}
$file = static::getSessionFile($session);
static::checkOrCreateSessionFolder($file);
$file = Files::getSessionFile($session);
Files::checkOrCreateSessionFolder($file);
$settings = array_replace_recursive((array) Config::getInstance()->get('telegram'), $settings);
$instance = new MadelineProto\API($file, $settings);
$instance->async(true);
@ -190,7 +146,7 @@ class Client
private function loop(MadelineProto\API $instance, callable $callback = null): void
{
$sessionName = static::getSessionName($instance->session);
$sessionName = Files::getSessionName($instance->session);
try {
$callback ? $instance->loop($callback) : $instance->loop();
} catch (\Throwable $e) {

View File

@ -3,7 +3,7 @@
namespace TelegramApiServer\EventObservers;
use danog\MadelineProto\APIWrapper;
use TelegramApiServer\Client;
use TelegramApiServer\Files;
class EventHandler extends \danog\MadelineProto\EventHandler
{
@ -12,7 +12,7 @@ class EventHandler extends \danog\MadelineProto\EventHandler
public function __construct(APIWrapper $MadelineProto)
{
$this->sessionName = Client::getSessionName($MadelineProto->session);
$this->sessionName = Files::getSessionName($MadelineProto->session);
if (empty(static::$instances[$this->sessionName])) {
static::$instances[$this->sessionName] = true;
parent::__construct($MadelineProto);

62
src/Files.php Normal file
View File

@ -0,0 +1,62 @@
<?php
namespace TelegramApiServer;
class Files
{
public static string $sessionExtension = '.madeline';
public static string $sessionFolder = 'sessions';
public static function checkOrCreateSessionFolder(string $session): void
{
$directory = dirname($session);
if ($directory && $directory !== '.' && !is_dir($directory)) {
$parentDirectoryPermissions = fileperms(ROOT_DIR);
if (!mkdir($directory, $parentDirectoryPermissions, true) && !is_dir($directory)) {
throw new RuntimeException(sprintf('Directory "%s" was not created', $directory));
}
}
}
public static function getSessionName(?string $sessionFile): ?string
{
if (!$sessionFile) {
return null;
}
preg_match(
'~' . Files::$sessionFolder . "/(?'sessionName'.*?)" . Files::$sessionExtension . '$~',
$sessionFile,
$matches
);
return $matches['sessionName'] ?? null;
}
/**
* @param string|null $session
*
* @return string|null
*/
public static function getSessionFile(?string $session): ?string
{
if (!$session) {
return null;
}
$session = trim(trim($session), '/');
$session = Files::$sessionFolder . '/' . $session . Files::$sessionExtension;
$session = str_replace('//', '/', $session);
return $session;
}
public static function globRecursive($pattern, $flags = 0): array
{
$files = glob($pattern, $flags) ?: [];
foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
$files = [...$files, ...static::globRecursive($dir.'/'.basename($pattern), $flags)];
}
return $files;
}
}

View File

@ -6,6 +6,7 @@ use Amp\Promise;
use danog\MadelineProto;
use danog\MadelineProto\MTProto;
use TelegramApiServer\Client;
use TelegramApiServer\Files;
use function Amp\call;
class SystemApiExtensions
@ -60,7 +61,7 @@ class SystemApiExtensions
$sessions[$session] = [
'session' => $session,
'file' => Client::getSessionFile($session),
'file' => Files::getSessionFile($session),
'status' => $status,
];
}
@ -74,7 +75,7 @@ class SystemApiExtensions
public function removeSessionFile($session)
{
return call(static function() use($session) {
$file = Client::getSessionFile($session);
$file = Files::getSessionFile($session);
if (is_file($file)) {
yield \Amp\File\unlink($file);
yield \Amp\File\unlink($file . '.lock');

View File

@ -2,22 +2,22 @@
namespace TelegramApiServer\Migrations;
use TelegramApiServer\Client;
use TelegramApiServer\Files;
class SessionsMigration
{
public static function move($rootDir = ROOT_DIR)
{
foreach (glob("$rootDir/*" . Client::$sessionExtension) as $oldFile) {
foreach (glob("$rootDir/*" . Files::$sessionExtension) as $oldFile) {
preg_match(
'~^' . "{$rootDir}(?'session'.*)" . preg_quote(Client::$sessionExtension, '\\') . '$~',
'~^' . "{$rootDir}(?'session'.*)" . preg_quote(Files::$sessionExtension, '\\') . '$~',
$oldFile,
$matches
);
if ($session = $matches['session'] ?? null) {
$session = Client::getSessionFile($session);
Client::checkOrCreateSessionFolder($session);
$session = Files::getSessionFile($session);
Files::checkOrCreateSessionFolder($session);
rename($oldFile, "{$rootDir}/{$session}");
rename("{$oldFile}.lock", "{$rootDir}/{$session}.lock");