Code Style

This commit is contained in:
Alexander Pankratov 2019-03-19 02:36:20 +03:00
parent d0c4a19139
commit b6d12bead9
7 changed files with 196 additions and 185 deletions

View File

@ -9,6 +9,6 @@ if (!class_exists('TelegramSwooleClient')) {
chdir($root);
}
//Check if root env file hash been loaded (in case plugin installed in existing project)
if (!getenv('SWOOLE_SERVER_ADDRESS')){
if (!getenv('SWOOLE_SERVER_ADDRESS')) {
(new Dotenv\Dotenv($root))->load();
}

View File

@ -3,49 +3,49 @@
return [
'swoole' => [
'server' => [
'address' => (string) getenv('SWOOLE_SERVER_ADDRESS'),
'port' => (string) getenv('SWOOLE_SERVER_PORT'),
'address' => (string)getenv('SWOOLE_SERVER_ADDRESS'),
'port' => (string)getenv('SWOOLE_SERVER_PORT'),
],
'options'=> [
'worker_num' => (int) getenv('SWOOLE_WORKER_NUM'),
'http_compression' => (bool) getenv('SWOOLE_HTTP_COMPRESSION'),
'options' => [
'worker_num' => (int)getenv('SWOOLE_WORKER_NUM'),
'http_compression' => (bool)getenv('SWOOLE_HTTP_COMPRESSION'),
]
],
'telegram' => [
'app_info' => [ // obtained in https://my.telegram.org
'api_id' => getenv('TELEGRAM_API_ID'),
'api_hash' => getenv('TELEGRAM_API_HASH'),
'api_id' => getenv('TELEGRAM_API_ID'),
'api_hash' => getenv('TELEGRAM_API_HASH'),
],
'logger' => [ // Logger settings
'logger' => 3, // 0 - Logs disabled, 3 - echo logs.
'logger_level' => 2, // Logging level, available logging levels are: ULTRA_VERBOSE - 0, VERBOSE - 1 , NOTICE - 2, WARNING - 3, ERROR - 4, FATAL_ERROR - 5.
'logger' => 3, // 0 - Logs disabled, 3 - echo logs.
'logger_level' => 2, // Logging level, available logging levels are: ULTRA_VERBOSE - 0, VERBOSE - 1 , NOTICE - 2, WARNING - 3, ERROR - 4, FATAL_ERROR - 5.
],
'updates' => [
'handle_updates' => false, // Should I handle updates?
'handle_old_updates' => false, // Should I handle old updates on startup?
'handle_updates' => false, // Should I handle updates?
'handle_old_updates' => false, // Should I handle old updates on startup?
],
'connection_settings' => [
'all' => [
'proxy' => '\SocksProxy',
'proxy_extra' => [
'address' => getenv('TELEGRAM_PROXY_ADDRESS'),
'port' => getenv('TELEGRAM_PROXY_PORT'),
'username' => getenv('TELEGRAM_PROXY_USERNAME'),
'password' => getenv('TELEGRAM_PROXY_PASSWORD'),
'proxy' => '\SocksProxy',
'proxy_extra' => [
'address' => getenv('TELEGRAM_PROXY_ADDRESS'),
'port' => getenv('TELEGRAM_PROXY_PORT'),
'username' => getenv('TELEGRAM_PROXY_USERNAME'),
'password' => getenv('TELEGRAM_PROXY_PASSWORD'),
]
]
]
],
'curl' => [
'proxy' => [
'address' => getenv('CURL_PROXY_ADDRESS'),
'port' => getenv('CURL_PROXY_PORT'),
'username' => getenv('CURL_PROXY_USERNAME'),
'password' => getenv('CURL_PROXY_PASSWORD'),
'address' => getenv('CURL_PROXY_ADDRESS'),
'port' => getenv('CURL_PROXY_PORT'),
'username' => getenv('CURL_PROXY_USERNAME'),
'password' => getenv('CURL_PROXY_PASSWORD'),
]
],
'api' => [
'ip_whitelist' => json_decode(getenv('API_CLIENT_WHITELIST'),true),
'ip_whitelist' => json_decode(getenv('API_CLIENT_WHITELIST'), true),
'index_message' => getenv('API_INDEX_MESSAGE'),
],
];

View File

@ -7,7 +7,7 @@ if (PHP_SAPI !== 'cli') {
}
$shortopts = 'a::p::s::';
$longopts = [
$longopts = [
'address::', // ip адресс сервера, необязательное значение
'port::', // порт сервера, необязательное значение
'session::', //префикс session файла
@ -15,10 +15,10 @@ $longopts = [
];
$options = getopt($shortopts, $longopts);
$options = [
'address' => $options['address'] ?? $options['a'] ?? '',
'port' => $options['port'] ?? $options['p'] ?? '',
'session' => $options['session'] ?? $options['s'] ?? '',
'help' => isset($options['help']),
'address' => $options['address'] ?? $options['a'] ?? '',
'port' => $options['port'] ?? $options['p'] ?? '',
'session' => $options['session'] ?? $options['s'] ?? '',
'help' => isset($options['help']),
];
if ($options['help']) {
@ -44,7 +44,7 @@ Example:
if ($options['session']) {
$sessionFile = "{$root}/{$options['session']}_session.madeline";
} else {
$sessionFile = "{$root}/session.madeline";
$sessionFile = "{$root}/session.madeline";
}
$client = new \TelegramSwooleClient\Client($sessionFile);

View File

@ -2,12 +2,14 @@
namespace TelegramSwooleClient;
use \danog\MadelineProto;
use danog\MadelineProto;
class Client {
class Client
{
public $MadelineProto;
private $sessionFile;
/**
* Client constructor.
*/
@ -23,7 +25,8 @@ class Client {
$this->connect();
}
public function connect() {
public function connect()
{
//При каждой инициализации настройки обновляются из массива $config
echo PHP_EOL . 'Starting telegram client ...' . PHP_EOL;
$time = microtime(true);
@ -54,14 +57,14 @@ class Client {
public function getHistory($data): array
{
$data = array_merge([
'peer' => '',
'offset_id' => 0,
'offset_date' => 0,
'add_offset' => 0,
'limit' => 0,
'max_id' => 0,
'min_id' => 0,
'hash' => 0,
'peer' => '',
'offset_id' => 0,
'offset_date' => 0,
'add_offset' => 0,
'limit' => 0,
'max_id' => 0,
'min_id' => 0,
'hash' => 0,
], $data);
return $this->MadelineProto->messages->getHistory($data);
@ -80,32 +83,33 @@ class Client {
* </pre>
* @return array
*/
public function copyMessages($data):array {
public function copyMessages($data): array
{
$data = array_merge([
'from_peer' => '',
'to_peer' => '',
'id' => [],
],$data);
'to_peer' => '',
'id' => [],
], $data);
$response = $this->MadelineProto->channels->getMessages([
'channel' => $data['from_peer'],
'id' => $data['id'],
'channel' => $data['from_peer'],
'id' => $data['id'],
]);
$result = [];
if (!$response || !is_array($response) || !array_key_exists('messages', $response)){
if (!$response || !is_array($response) || !array_key_exists('messages', $response)) {
return $result;
}
foreach ($response['messages'] as $message) {
usleep(mt_rand(300,2000)*1000);
usleep(mt_rand(300, 2000) * 1000);
$messageData = [
'message' => $message['message'] ?? '',
'peer' => $data['to_peer'],
'entities' => $message['entities'] ?? [],
'message' => $message['message'] ?? '',
'peer' => $data['to_peer'],
'entities' => $message['entities'] ?? [],
];
if (
static::hasMedia($message, false)
static::hasMedia($message, false)
) {
$messageData['media'] = $message; //MadelineProto сама достанет все media из сообщения.
$result[] = $this->sendMedia($messageData);
@ -133,11 +137,11 @@ class Client {
public function searchGlobal(array $data): array
{
$data = array_merge([
'q' => '',
'offset_id' => 0,
'offset_date' => 0,
'limit' => 10,
],$data);
'q' => '',
'offset_id' => 0,
'offset_date' => 0,
'limit' => 10,
], $data);
return $this->MadelineProto->messages->searchGlobal($data);
}
@ -156,10 +160,10 @@ class Client {
public function sendMessage($data = []): array
{
$data = array_merge([
'peer' => '',
'message' => '',
'reply_to_msg_id' => 0,
'parse_mode' => 'HTML',
'peer' => '',
'message' => '',
'reply_to_msg_id' => 0,
'parse_mode' => 'HTML',
], $data);
return $this->MadelineProto->messages->sendMessage($data);
@ -181,136 +185,139 @@ class Client {
public function sendMedia($data = []): array
{
$data = array_merge([
'peer' => '',
'message' => '',
'media' => [],
'reply_to_msg_id' => 0,
'parse_mode' => 'HTML',
'peer' => '',
'message' => '',
'media' => [],
'reply_to_msg_id' => 0,
'parse_mode' => 'HTML',
], $data);
return $this->MadelineProto->messages->sendMedia($data);
}
/**
* Загружает медиафайл из указанного сообщения во временный файл
*
* Внимание! Необходимо самостоятельно удалять временные файлы после их использования
* @param $data
* @return array
*/
public function getMedia($data) {
$data = array_merge([
'channel' =>'',
'id' => [0],
'message' => [],
/**
* Загружает медиафайл из указанного сообщения во временный файл
*
* Внимание! Необходимо самостоятельно удалять временные файлы после их использования
* @param $data
* @return array
*/
public function getMedia($data)
{
$data = array_merge([
'channel' => '',
'id' => [0],
'message' => [],
'size_limit' => 0,
],$data);
], $data);
if (!$data['message']) {
$response = $this->MadelineProto->channels->getMessages($data);
$message = $response['messages'][0];
} else {
$message = $data['message'];
}
if (!$data['message']) {
$response = $this->MadelineProto->channels->getMessages($data);
$message = $response['messages'][0];
} else {
$message = $data['message'];
}
if (!static::hasMedia($message)) {
throw new \UnexpectedValueException('Message has no media');
}
if (!static::hasMedia($message)) {
throw new \UnexpectedValueException('Message has no media');
}
$info = $this->MadelineProto->get_download_info($message);
$info = $this->MadelineProto->get_download_info($message);
if ($data['size_limit']) {
if ($info['size'] > $data['size_limit']) {
throw new \OutOfRangeException(
"Media exceeds size limit. Size: {$info['size']} bytes; limit: {$data['size_limit']} bytes"
if ($data['size_limit']) {
if ($info['size'] > $data['size_limit']) {
throw new \OutOfRangeException(
"Media exceeds size limit. Size: {$info['size']} bytes; limit: {$data['size_limit']} bytes"
);
}
}
$file = tempnam(sys_get_temp_dir(), 'telegram_media_');
$this->MadelineProto->download_to_file($message, $file);
$file = tempnam(sys_get_temp_dir(), 'telegram_media_');
$this->MadelineProto->download_to_file($message, $file);
return [
'headers'=> [
['Content-Length',$info['size']],
['Content-Type',$info['mime']]
],
'file' => $file,
];
}
return [
'headers' => [
['Content-Length', $info['size']],
['Content-Type', $info['mime']]
],
'file' => $file,
];
}
/**
* Загружает превью медиафайла из указанного сообщения во временный файл
*
* Внимание! Необходимо самостоятельно удалять временные файлы после их использования
* @param array $data
* @return array
*/
public function getMediaPreview(array $data){
$data = array_merge([
'channel' =>'',
'id' => [0],
'message' => [],
],$data);
/**
* Загружает превью медиафайла из указанного сообщения во временный файл
*
* Внимание! Необходимо самостоятельно удалять временные файлы после их использования
* @param array $data
* @return array
*/
public function getMediaPreview(array $data)
{
$data = array_merge([
'channel' => '',
'id' => [0],
'message' => [],
], $data);
if (!$data['message']) {
$response = $this->MadelineProto->channels->getMessages($data);
$message = $response['messages'][0];
} else {
$message = $data['message'];
}
if (!$data['message']) {
$response = $this->MadelineProto->channels->getMessages($data);
$message = $response['messages'][0];
} else {
$message = $data['message'];
}
if (!static::hasMedia($message)) {
throw new \UnexpectedValueException('Message has no media');
}
if (!static::hasMedia($message)) {
throw new \UnexpectedValueException('Message has no media');
}
$media = $message['media'][array_key_last($message['media'])];
switch (true) {
case isset($media['sizes']):
$thumb = $media['sizes'][array_key_last($media['sizes'])];
break;
case isset($media['thumb']['size']):
$thumb = $media['thumb'];
break;
$media = $message['media'][array_key_last($message['media'])];
switch (true) {
case isset($media['sizes']):
$thumb = $media['sizes'][array_key_last($media['sizes'])];
break;
case isset($media['thumb']['size']):
$thumb = $media['thumb'];
break;
case !empty($media['thumbs']):
$thumb = $media['thumbs'][array_key_last($media['thumbs'])];
break;
case isset($media['photo']['sizes']):
$thumb = $media['photo']['sizes'][array_key_last($media['photo']['sizes'])];
break;
default:
throw new \UnexpectedValueException('Message has no preview');
case isset($media['photo']['sizes']):
$thumb = $media['photo']['sizes'][array_key_last($media['photo']['sizes'])];
break;
default:
throw new \UnexpectedValueException('Message has no preview');
}
$info = $this->MadelineProto->get_download_info($thumb);
$file = tempnam(sys_get_temp_dir(), 'telegram_media_preview_');
$this->MadelineProto->download_to_file($thumb, $file);
}
$info = $this->MadelineProto->get_download_info($thumb);
$file = tempnam(sys_get_temp_dir(), 'telegram_media_preview_');
$this->MadelineProto->download_to_file($thumb, $file);
return [
'headers'=> [
['Content-Length', $info['size']],
['Content-Type', $info['mime']],
],
'file' => $file,
];
}
return [
'headers' => [
['Content-Length', $info['size']],
['Content-Type', $info['mime']],
],
'file' => $file,
];
}
/**
* Проверяет есть ли подходящие медиа у сообщения
* @param array $message
* @return bool
*/
private static function hasMedia($message = [], $useWebPage = true){
$media = $message['media'] ?? [];
if (empty($media['_'])) {
return false;
}
if ($media['_'] == 'messageMediaWebPage'){
return $useWebPage;
}
return true;
}
/**
* Проверяет есть ли подходящие медиа у сообщения
* @param array $message
* @return bool
*/
private static function hasMedia($message = [], $useWebPage = true)
{
$media = $message['media'] ?? [];
if (empty($media['_'])) {
return false;
}
if ($media['_'] == 'messageMediaWebPage') {
return $useWebPage;
}
return true;
}
}

View File

@ -50,17 +50,19 @@ class Config
* @param null $default
* @return mixed|null
*/
public function get($key = '', $default = null) {
public function get($key = '', $default = null)
{
return $this->findByKey($key) ?? $default;
}
private function findByKey($key) {
$key = (string) $key;
private function findByKey($key)
{
$key = (string)$key;
$path = explode('.', $key);
$value = &$this->config;
foreach($path as $pathKey) {
if (!is_array($value) || !array_key_exists($pathKey,$value)) {
foreach ($path as $pathKey) {
if (!is_array($value) || !array_key_exists($pathKey, $value)) {
return;
}
$value = &$value[$pathKey];

View File

@ -11,7 +11,7 @@ class RequestCallback
private const PAGES = ['index', 'api'];
/** @var string */
private $indexMessage;
/** @var array */
/** @var array */
private $ipWhiteList;
private $path = [];
public $page = [
@ -20,7 +20,7 @@ class RequestCallback
],
'success' => 0,
'errors' => [],
'code' => 200,
'code' => 200,
'response' => null,
];
private $parameters = [];
@ -35,8 +35,8 @@ class RequestCallback
*/
public function __construct(\Swoole\Http\Request $request, \Swoole\Http\Response $response, Client $client, $http_server)
{
$this->ipWhiteList = (array) Config::getInstance()->get('api.ip_whitelist', []);
$this->indexMessage = (string) Config::getInstance()->get('api.index_message', 'Welcome to telegram client!');
$this->ipWhiteList = (array)Config::getInstance()->get('api.ip_whitelist', []);
$this->indexMessage = (string)Config::getInstance()->get('api.index_message', 'Welcome to telegram client!');
$this->client = $client;
$this->server = $http_server;
$this->parsePost($request)
@ -63,7 +63,7 @@ class RequestCallback
$this->path = array_values(array_filter(explode('/', $uri)));
if (!$this->path || $this->path[0] !== 'api') {
$this->page['response'] = $this->indexMessage;
} elseif (!in_array($this->path[0],self::PAGES, true)) {
} elseif (!in_array($this->path[0], self::PAGES, true)) {
$this->setPageCode(404);
$this->page['errors'][] = 'Incorrect path';
}
@ -76,7 +76,8 @@ class RequestCallback
* @param array $post
* @return RequestCallback
*/
private function resolveRequest(array $get, array $post):self {
private function resolveRequest(array $get, array $post): self
{
$this->parameters = array_values(array_merge($get, $post));
$this->api = $this->path[1] ?? '';
return $this;
@ -103,18 +104,19 @@ class RequestCallback
return $this;
}
private function callApi(\Swoole\Http\Request $request){
private function callApi(\Swoole\Http\Request $request)
{
if (!in_array($request->server['remote_addr'], $this->ipWhiteList, true)) {
throw new \Exception('API not available');
}
if (method_exists($this->client,$this->api)){
if (method_exists($this->client, $this->api)) {
return $this->client->{$this->api}(...$this->parameters);
}
//Проверяем нет ли в MadilineProto такого метода.
$this->api = explode('.', $this->api);
switch (count($this->api)){
switch (count($this->api)) {
case 1:
return $this->client->MadelineProto->{$this->api[0]}(...$this->parameters);
break;
@ -133,8 +135,9 @@ class RequestCallback
* @param \Throwable $e
* @return RequestCallback
*/
private function setError(\Throwable $e):self {
if ($e instanceof \Error){
private function setError(\Throwable $e): self
{
if ($e instanceof \Error) {
//Это критическая ошибка соедниения. Необходим полный перезапуск.
$this->setPageCode(400);
$this->page['errors'][] = [

View File

@ -23,8 +23,7 @@ class Server
$http_server->set($this->config['options']);
$http_server->on('request', function(\Swoole\Http\Request $request, \Swoole\Http\Response $response) use($client, $http_server)
{
$http_server->on('request', function (\Swoole\Http\Request $request, \Swoole\Http\Response $response) use ($client, $http_server) {
//На каждый запрос должны создаваться новые экземпляры классов парсера и коллбеков,
//иначе их данные будут в области видимости всех запросов.
@ -44,10 +43,10 @@ class Server
private function setConfig(array $config = []): self
{
$config = [
'server'=> array_filter($config)
'server' => array_filter($config)
];
foreach (['server','options'] as $key) {
foreach (['server', 'options'] as $key) {
$this->config[$key] = array_merge(
Config::getInstance()->get("swoole.{$key}", []),
$config[$key] ?? []