XF2 [8WR] XenRio 2 (Streams) PRO

XF2 [8WR] XenRio 2 (Streams) PRO 2.1.1.6

Нет прав для скачивания
Так как раз на новой, что на данный момент последняя не работают, все ранее добавленные нормально, но новые не добавляет.
 
ШОК! Для того чтобы заработали стримы на 2.0.1.4 нужно просто изменить...
Я понимаю, что многая часть пользователей знает что изменить, где и как. А остальная, типа меня не знает. И знаю, что когда тут спрашиваешь, начинается стеб. Нет желания подсказывать, зачем поддевать то. Нуждаюсь в помощи, перехожу по ссылкам с письма о новом ответе с надеждой, а тут под*.. кхм, издевка.
 
Я понимаю, что многая часть пользователей знает что изменить, где и как. А остальная, типа меня не знает. И знаю, что когда тут спрашиваешь, начинается стеб. Нет желания подсказывать, зачем поддевать то. Нуждаюсь в помощи, перехожу по ссылкам с письма о новом ответе с надеждой, а тут под*.. кхм, издевка.

Я могу объяснить зачем:
Вы приходите сюда, на форум на котором делятся плагинами, и пишите - у меня есть новая версия плагина, и в ней ошибки" (Или я что-то не правильно понял?) При этом видите, что тут выложена старая версия и соответственно у большей части пользователей она и стоит. Сами подумайте, стоит ли делиться решением с человеком, который говорит - у меня есть новый плагин, но я его вам не дам, просто помогите мне =) Да и как можно решить проблему последней версии, если ее у нас нет)
 
Последнее редактирование:
Я могу объяснить зачем:
Вы приходите сюда, на форум на котором делятся плагинами, и пишите - у меня есть новая версия плагина, и в ней ошибки" (Или я что-то не правильно понял?) При этом видите, что тут выложена старая версия и соответственно у большей части пользователей она и стоит. Сами подумайте, стоит ли делиться решением с человеком, который говорит - у меня есть новый плагин, но я его вам не дам, просто помогите мне =) Да и как можно решить проблему последней версии, если ее у нас нет)
Резонно. Научите обновлять ресурсы, ранее такого не проделывал.
 
Просто вложением архив оставляете, а мы уже по возможности обновляем.
 
для 2.0.1.4 я два файла изменил, там с этим GuzzleHttp было связано и на 2.0.1.4 у меня все работает, хоть и вылазят предупреждения несоответствия при проверке файлов, но это не страшно

/src/addons/EWR/Rio/Api/Twitch.php
/src/addons//EWR/Rio/Api/YouTube.php

Для твича

PHP:
<?php

namespace EWR\Rio\Api;

use XF\Mvc\Entity\AbstractCollection;
use XF\Mvc\Entity\Repository;

class Twitch extends Repository
{
    static $base = 'https://api.twitch.tv/helix/';
    static $type = 'live';
    static $limit = 100;
    static $maximum = 500;
    
    public static function dumpChannel($service, $matches)
    {
        try
        {
            $client = \XF::app()->http()->client();
            $response = $client->get(self::$base.'users', [
                'headers' => [
                    'Client-ID' => $service->service_apikey,
                ],
                'query' => [
                    'login' => $matches['sval1'],
                ],
            ]);
            $json = \GuzzleHttp\json_decode($response->getBody(), true);
        }
        catch (\Exception $e)
        {
            throw new \XF\PrintableException(\XF::phrase('error_occurred_while_connecting_with_x',
                ['provider' => $service->service_name]));
        }
        
        if (empty($json['data'][0]))
        {
            throw new \XF\PrintableException(\XF::phrase('EWRrio_channel_url_did_not_match_services'));
        }
        
        $json = $json['data'][0];
        
        $channel = array(
            'service_id' => $service->service_id,
            'channel_value1' => $json['login'],
            'channel_value2' => $json['id'],
            'channel_title' => $json['display_name'],
            'channel_thumb' => $json['profile_image_url'],
            'channel_offline' => str_replace('1920x1080', '320x180', $json['offline_image_url']),
        );
        
        return $channel;
    }

    public static function dumpStreams($service, $restriction, $channels, $spellings)
    {
        $streams = array();
        
        if ($restriction == '000')
        {
            $streams = self::dumpAll($service, $restriction, $channels, $spellings);
        }
        else
        {
            if ($restriction[0] && !empty($channels))
            {
                $streams = array_merge($streams, self::dumpChannels($service, $restriction, $channels, $spellings));
            }
            
            if ($restriction[1] && !$restriction[2] && !empty($spellings))
            {
                $streams = array_merge($streams, self::dumpGames($service, $restriction, $channels, $spellings));
            }
        }
        
        return $streams;
    }
    
    private static function dumpAll($service, $restriction, $channels, $spellings)
    {
        $cursor = '';
        $scrape = true;
        $offset = 0;
        $streams = array();
        
        do
        {
            try
            {
                $client = \XF::app()->http()->client();
                $response = $client->get(self::$base.'streams', [
                    'headers' => [
                        'Client-ID' => $service->service_apikey,
                    ],
                    'query' => [
                        'type' => self::$type,
                        'first' => self::$limit,
                        'after' => $cursor,
                    ],
                ]);
                $jsonS = $response = \GuzzleHttp\json_decode($response->getBody(), true);
            }
            catch (\Exception $e)
            {
                return $streams;
            }
        
            if (empty($jsonS['data'])) { return $streams; }
            $jsonU = self::getJsonU($jsonS['data'], $service);
            if (empty($jsonU)) { return $streams; }
            $jsonG = self::getJsonG($jsonS['data'], $service);
            $cursor = $jsonS['pagination']['cursor'];
        
            foreach ($jsonS['data'] AS $stream)
            {
                if (empty($jsonU[$stream['user_id']])) { continue; }
                
                $stream['channel'] = $jsonU[$stream['user_id']];
                $stream['game'] = !empty($jsonG[$stream['game_id']]) ? $jsonG[$stream['game_id']] : null;
                
                $gameId = !empty($stream['game_id']) ? $stream['game_id'] : false;
                $spelling = !empty($spellings[$gameId]) ? $spellings[$gameId] : false;
                
                $chanId = strtolower($service->service_id.':'.$stream['channel']['login']);
                $channel = !empty($channels[$chanId]) ? $channels[$chanId] : false;
                
                $streams[$chanId] = self::buildStream($stream, $service, $channel, $spelling);
            }
            
            $offset += self::$limit;
            if (count($jsonS['data']) < self::$limit || $offset >= self::$maximum)
            {
                $scrape = false;
            }
        }
        while ($scrape);
        
        return $streams;
    }
    
    private static function dumpChannels($service, $restriction, $channels, $spellings)
    {
        $channelIds = array();
        foreach ($channels AS $channel)
        {
            $channelIds[] = $channel->channel_value2;
        }

        $cursor = '';
        $scrape = true;
        $offset = 0;
        $streams = array();
        
        do
        {
            try
            {
                $client = \XF::app()->http()->client();
                $response = $client->get(self::$base.'streams', [
                    'headers' => [
                        'Client-ID' => $service->service_apikey,
                    ],
                    'query' => [
                        'user_id' => $channelIds,
                        'type' => self::$type,
                        'first' => self::$limit,
                        'after' => $cursor,
                    ],
                ]);
                $jsonS = $response = \GuzzleHttp\json_decode($response->getBody(), true);
            }
            catch (\Exception $e)
            {
                return $streams;
            }
            
            if (empty($jsonS['data'])) { return $streams; }
            $jsonU = self::getJsonU($jsonS['data'], $service);
            if (empty($jsonU)) { return $streams; }
            $jsonG = self::getJsonG($jsonS['data'], $service);
            $cursor = $jsonS['pagination']['cursor'];
            
            foreach ($jsonS['data'] AS $stream)
            {
                if (empty($jsonU[$stream['user_id']])) { continue; }
                
                $stream['channel'] = $jsonU[$stream['user_id']];
                $stream['game'] = !empty($jsonG[$stream['game_id']]) ? $jsonG[$stream['game_id']] : null;
                
                $gameId = !empty($stream['game_id']) ? $stream['game_id'] : false;
                $spelling = !empty($spellings[$gameId]) ? $spellings[$gameId] : false;
                
                if ($restriction[2] && empty($spellings[$gameId])) { continue; }
                
                $chanId = strtolower($service->service_id.':'.$stream['channel']['login']);
                $channel = !empty($channels[$chanId]) ? $channels[$chanId] : false;
                
                $streams[$chanId] = self::buildStream($stream, $service, $channel, $spelling);
            }
            
            $offset += self::$limit;
            if (count($jsonS['data']) < self::$limit || $offset >= (self::$maximum / 2))
            {
                $scrape = false;
            }
        }
        while ($scrape);
        
        return $streams;
    }
    
    private static function dumpGames($service, $restriction, $channels, $spellings)
    {
        $gameIds = array();
        foreach ($spellings AS $spelling)
        {
            $gameIds[] = $spelling->spelling;
        }

        $cursor = '';
        $scrape = true;
        $offset = 0;
        $streams = array();
        
        do
        {
            try
            {
                $client = \XF::app()->http()->client();
                $response = $client->get(self::$base.'streams', [
                    'headers' => [
                        'Client-ID' => $service->service_apikey,
                    ],
                    'query' => [
                        'game_id' => $gameIds,
                        'type' => self::$type,
                        'first' => self::$limit,
                        'after' => $cursor,
                    ],
                ]);
                $jsonS = $response = \GuzzleHttp\json_decode($response->getBody(), true);
            }
            catch (\Exception $e)
            {
                return $streams;
            }
            
            if (empty($jsonS['data'])) { return $streams; }
            $jsonU = self::getJsonU($jsonS['data'], $service);
            if (empty($jsonU)) { return $streams; }
            $jsonG = self::getJsonG($jsonS['data'], $service);
            $cursor = $jsonS['pagination']['cursor'];
            
            foreach ($jsonS['data'] AS $stream)
            {
                if (empty($jsonU[$stream['user_id']])) { continue; }
                
                $stream['channel'] = $jsonU[$stream['user_id']];
                $stream['game'] = !empty($jsonG[$stream['game_id']]) ? $jsonG[$stream['game_id']] : null;
                
                $gameId = !empty($stream['game_id']) ? $stream['game_id'] : false;
                $spelling = !empty($spellings[$gameId]) ? $spellings[$gameId] : false;
                
                $chanId = strtolower($service->service_id.':'.$stream['channel']['login']);
                $channel = !empty($channels[$chanId]) ? $channels[$chanId] : false;
                
                $streams[$chanId] = self::buildStream($stream, $service, $channel, $spelling);
            }
            
            $offset += self::$limit;
            if (count($jsonS['data']) < self::$limit || $offset >= (self::$maximum / 2))
            {
                $scrape = false;
            }
        }
        while ($scrape);
        
        return $streams;
    }
    
    private static function buildStream($stream, $service, $channel = false, $spelling = false)
    {
        $featured = ($spelling && $spelling->Game->game_featured) ||
                    ($channel && $channel->channel_featured) ? 1 : 0;
        
        return [
            'channel_id' => $channel ? $channel->channel_id : 0,
            'game_id' => $spelling ? $spelling->game_id : 0,
            'service_id' => $service->service_id,
            'stream_value1' => strtolower($stream['channel']['login']),
            'stream_value2' => $stream['channel']['id'],
            'stream_title' => $stream['channel']['display_name'],
            'stream_status' => !empty($stream['title']) ? $stream['title'] : '',
            'stream_game' => !empty($stream['game']) ? $stream['game']['name'] : '',
            'stream_viewers' => $stream['viewer_count'],
            'stream_preview' => str_replace('{width}x{height}', '320x180', $stream['thumbnail_url']),
            'stream_thumb' => !empty($stream['channel']['profile_image_url']) ? $stream['channel']['profile_image_url'] : '',
            'stream_featured' => $featured,
        ];
    }
    
    public static function dumpSpelling($service, $spelling)
    {
        if (!is_numeric($spelling))
        {
            try
            {
                $client = \XF::app()->http()->client();
                $response = $client->get(self::$base.'games', [
                    'headers' => [
                        'Client-ID' => $service->service_apikey,
                    ],
                    'query' => [
                        'name' => $spelling,
                    ],
                ]);
                $json = \GuzzleHttp\json_decode($response->getBody(), true);
            }
            catch (\Exception $e)
            {
                throw new \XF\PrintableException(\XF::phrase('error_occurred_while_connecting_with_x',
                    ['provider' => $service->service_name]));
            }
        
            if (empty($json['data'][0]))
            {
                throw new \XF\PrintableException(\XF::phrase('EWRrio_game_x_not_found_in_y', [
                    'game' => $spelling,
                    'provider' => $service->service_name
                ]));
            }
            
            $spelling = $json['data'][0]['id'];
        }
        
        return [
            'service_id' => $service->service_id,
            'spelling' => $spelling
        ];
    }
    
    private static function getJsonU($jsonS, $service)
    {
        $channelIds = array();
        
        foreach ($jsonS AS $stream)
        {
            $channelIds[] = $stream['user_id'];
        }
        
        try
        {
            $client = \XF::app()->http()->client();
            $response = $client->get(self::$base.'users', [
                'headers' => [
                    'Client-ID' => $service->service_apikey,
                ],
                'query' => [
                    'id' => $channelIds,
                    'first' => self::$limit,
                ],
            ]);
            $jsonU = $response = \GuzzleHttp\json_decode($response->getBody(), true);
        }
        catch (\Exception $e)
        {
            return false;
        }
        
        if (empty($jsonU['data'])) { return false; }
        
        foreach ($jsonU['data'] AS $key => $channel)
        {
            $jsonU[$channel['id']] = $channel;
        }
        unset($jsonU['data']);
        
        return $jsonU;
    }
    
    private static function getJsonG($jsonS, $service)
    {
        $gameIds = array();
        
        foreach ($jsonS AS $stream)
        {
            $gameIds[] = $stream['game_id'];
        }
        
        try
        {
            $client = \XF::app()->http()->client();
            $response = $client->get(self::$base.'games', [
                'headers' => [
                    'Client-ID' => $service->service_apikey,
                ],
                'query' => [
                    'id' => $gameIds,
                    'first' => self::$limit,
                ],
            ]);
            $jsonG = $response = \GuzzleHttp\json_decode($response->getBody(), true);
        }
        catch (\Exception $e)
        {
            return false;
        }
        
        if (empty($jsonG['data'])) { return false; }
        
        foreach ($jsonG['data'] AS $key => $game)
        {
            $jsonG[$game['id']] = $game;
        }
        unset($jsonG['data']);
        
        return $jsonG;
    }
}

Ютуб

PHP:
<?php

namespace EWR\Rio\Api;

use XF\Mvc\Entity\AbstractCollection;
use XF\Mvc\Entity\Repository;

class YouTube extends Repository
{
    static $base = 'https://www.googleapis.com/youtube/v3/';
    
    public static function dumpChannel($service, $matches)
    {
        if (!empty($matches['video']))
        {
            try
            {
                $client = \XF::app()->http()->client();
                $response = $client->get(self::$base.'videos', [
                    'query' => [
                        'part' => 'snippet',
                        'id' => $matches['video'],
                        'key' => $service->service_apikey
                    ],
                ]);
                $json = $response = \GuzzleHttp\json_decode($response->getBody(), true);
            }
            catch (\Exception $e)
            {
                throw new \XF\PrintableException(\XF::phrase('error_occurred_while_connecting_with_x',
                    ['provider' => $service->service_name]));
            }
            
            if (empty($json['items']))
            {
                throw new \XF\PrintableException(\XF::phrase('EWRrio_channel_url_did_not_match_services'));
            }
            
            $matches['sval1'] = $json['items'][0]['snippet']['channelId'];
        }
        else if (!empty($matches['user']))
        {
            try
            {
                $client = \XF::app()->http()->client();
                $response = $client->get(self::$base.'channels', [
                    'query' => [
                        'part' => 'id',
                        'forUsername' => $matches['user'],
                        'key' => $service->service_apikey
                    ],
                ]);
                $json = $response = \GuzzleHttp\json_decode($response->getBody(), true);
            }
            catch (\Exception $e)
            {
                throw new \XF\PrintableException(\XF::phrase('error_occurred_while_connecting_with_x',
                    ['provider' => $service->service_name]));
            }
    
            if (empty($json['items']))
            {
                throw new \XF\PrintableException(\XF::phrase('EWRrio_channel_url_did_not_match_services'));
            }
            
            $matches['sval1'] = $json['items'][0]['id'];
        }
        
        try
        {
            $client = \XF::app()->http()->client();
            $response = $client->get(self::$base.'channels', [
                'query' => [
                    'part' => 'snippet,brandingSettings',
                    'id' => $matches['sval1'],
                        'key' => $service->service_apikey
                ],
            ]);
            $json = $response = \GuzzleHttp\json_decode($response->getBody(), true);
        }
        catch (\Exception $e)
        {
            throw new \XF\PrintableException(\XF::phrase('error_occurred_while_connecting_with_x',
                ['provider' => $service->service_name]));
        }

        if (empty($json['items']))
        {
            throw new \XF\PrintableException(\XF::phrase('EWRrio_channel_url_did_not_match_services'));
        }
        
        $json = $json['items'][0];
        $thumb = end($json['snippet']['thumbnails']);
        
        $channel = array(
            'service_id' => $service->service_id,
            'channel_value1' => $json['id'],
            'channel_value2' => !empty($json['snippet']['customUrl']) ? $json['snippet']['customUrl'] : '',
            'channel_title' => $json['snippet']['title'],
            'channel_thumb' => $thumb['url'],
            'channel_offline' => !empty($json['brandingSettings']['image']['bannerTvLowImageUrl'])
                ? str_replace('/w854', '/w320', $json['brandingSettings']['image']['bannerTvLowImageUrl']) : '',
        );
        
        return $channel;
    }

    public static function dumpStreams($service, $restriction, $channels, $spellings)
    {
        $streams = array();
        
        if ($restriction == '000')
        {
        }
        else
        {
            if ($restriction[0] && !empty($channels))
            {
                $streams = array_merge($streams, self::dumpChannels($service, $restriction, $channels, $spellings));
            }
        }
        
        return $streams;
    }
    
    private static function dumpChannels($service, $restriction, $channels, $games)
    {
        $streams = array();
        
        foreach ($channels AS $channel)
        {
            try
            {
                $client = \XF::app()->http()->client();
                $response = $client->get(self::$base.'search', [
                    'query' => [
                        'part' => 'snippet',
                        'type' => 'video',
                        'eventType' => 'live',
                        'videoEmbeddable' => 'true',
                        'channelId' => $channel->channel_value1,
                        'key' => $service->service_apikey
                    ],
                ]);
                $json = $response = \GuzzleHttp\json_decode($response->getBody(), true);
            }
            catch (\Exception $e)
            {
                return $streams;
            }
            
            if (empty($json['items'])) { continue; }
            
            foreach ($json['items'] AS $stream)
            {
                try
                {
                    $client = \XF::app()->http()->client();
                    $response = $client->get(self::$base.'videos', [
                        'query' => [
                            'part' => 'snippet,liveStreamingDetails,topicDetails',
                            'id' => $stream['id']['videoId'],
                            'key' => $service->service_apikey
                        ],
                    ]);
                    $json = $response = \GuzzleHttp\json_decode($response->getBody(), true);
                }
                catch (\Exception $e)
                {
                    return $streams;
                }
                
                if (empty($json['items'])) { continue; }
                
                $stream = $json['items'][0];
            
                $chanId = strtolower($service->service_id.':'.$stream['snippet']['channelId']);
                
                $streams[$chanId] = self::buildStream($stream, $service, $channel);
            }
        }
        
        return $streams;
    }
    
    private static function buildStream($stream, $service, $channel = false, $spelling = false)
    {
        $featured = ($spelling && $spelling->Game->game_featured) ||
                    ($channel && $channel->channel_featured) ? 1 : 0;

        $title = !empty($stream['snippet']['channelTitle']) ? $stream['snippet']['channelTitle'] : $stream['id'];
        
        return [
            'channel_id' => $channel ? $channel->channel_id : 0,
            'game_id' => $spelling ? $spelling->game_id : 0,
            'service_id' => $service->service_id,
            'stream_value1' => $stream['snippet']['channelId'],
            'stream_value2' => $stream['id'],
            'stream_title' => $title,
            'stream_status' => $stream['snippet']['title'],
            'stream_game' => '',
            'stream_viewers' => !empty($stream['liveStreamingDetails']['concurrentViewers']) ? $stream['liveStreamingDetails']['concurrentViewers'] : 0,
            'stream_preview' => $stream['snippet']['thumbnails']['medium']['url'],
            'stream_thumb' => $channel ? $channel->channel_thumb : '',
            'stream_featured' => $featured,
        ];
    }
}
 
Ну как бы в обновлении автор это тоже сделал, но отвалилось именно добавление, а не воспроизведение существующих, на оффе на это жалуются.
Так-то всё работало, вот в чём суть и что человек пишет.
 
А для 2.1 ветки? Или аналогично?
 
Та ничего не нужно править, у Вас всё нормально уже в дополнении, это автора ждать, пока он одумается посмотреть.
Понял вас, да. Добавление с ноля или к уже готовым глючит. Спасибо за пояснения.
 
  • Мне нравится
Реакции: Sidd
Доброго времени суток, появилось 3 вопроса:
1. Почему при добавлении одного канала с твитч, подвязалось 500 каналов?
2. Есть ли какой то мануал по подвязке youtube, так как получил ключ api, вставил, канал добавляется и определяется, но стрима нет пишет ошибку.
3. Здесь так же писали о сортировке по играм, вопрос как?
 
Последнее редактирование:
А есть русификация к этой версии?
 
HAIM, Len, Понял, спасибо за ответы. А поиском пользоваться я умею ?
Вопрос был задан по конкретной версии.
 
Установка проходит успешно, но даже в разделе "навигации" не появляется вкладка streams. API от твича получил и в плагине сохранял. Каналы добавляются в настройках.
Но на самом форуме "тишина", как будто ничего и не устанавливалось, куда копать не знаю
 
Права групп смотрели?
 
  • Мне нравится
Реакции: Hope
Современный облачный хостинг провайдер | Aéza
Назад
Сверху Снизу