def _calculate_token(cls): credentials = { 'username': Configuration.get_configuration_parameter('VADERSTREAMS_USERNAME'), 'password': SecurityManager.decrypt_password( Configuration.get_configuration_parameter('VADERSTREAMS_PASSWORD')).decode(), } return base64.b64encode(json.dumps(credentials, separators=(',', ':')).encode()).decode()
def start_https_server(cls): try: Privilege.become_privileged_user() SecurityManager.determine_certificate_validity() cls._https_server_thread = cls._start_server(is_secure=True) except SSLError: logger.error( 'Failed to start HTTPS Server\n' 'Make sure the certificate and key files specified match\n' 'Certificate file path => %s\n' 'Key file path => %s', SecurityManager.get_certificate_file_path(), SecurityManager.get_key_file_path(), ) except OSError: error_message = ['Failed to start HTTPS Server'] certificate_or_key_file_not_found = False if not os.path.exists(SecurityManager.get_certificate_file_path()): certificate_or_key_file_not_found = True error_message.append( 'SSL file not found\n' 'Certificate file path => {0}'.format( SecurityManager.get_certificate_file_path())) if not os.path.exists(SecurityManager.get_key_file_path()): if certificate_or_key_file_not_found: error_message[1] = error_message[1].replace( 'SSL file', 'SSL files') error_message.append('Key file path => {0}'.format( SecurityManager.get_key_file_path())) else: certificate_or_key_file_not_found = True error_message.append( 'SSL file not found\n' 'Key file path => {0}'.format( SecurityManager.get_key_file_path())) if not certificate_or_key_file_not_found: (status, value_, traceback_) = sys.exc_info() error_message.append('\n'.join( traceback.format_exception(status, value_, traceback_))) logger.error('\n'.join(error_message)) finally: Privilege.become_unprivileged_user()
def _request_epg_json(cls, epg_json_path, epg_json_file_name, request_parameters): username = Configuration.get_configuration_parameter( 'VADERSTREAMS_USERNAME') password = SecurityManager.decrypt_password( Configuration.get_configuration_parameter( 'VADERSTREAMS_PASSWORD')).decode() url = '{0}{1}'.format(VaderStreamsConstants.BASE_URL, epg_json_path) logger.debug( 'Downloading %s\n' 'URL => %s\n' ' Parameters\n' ' username => %s\n' ' password => %s%s', epg_json_file_name, url, username, '\u2022' * len(password), '' if request_parameters is None or 'category_id' not in request_parameters else '\n category => {0}'.format(request_parameters['category_id']), ) requests_session = requests.Session() response = Utility.make_http_request( requests_session.get, url, params={ 'username': username, 'password': password, **request_parameters }, headers=requests_session.headers, cookies=requests_session.cookies.get_dict(), stream=True, ) if response.status_code == requests.codes.OK: response.raw.decode_content = True logger.trace(Utility.assemble_response_from_log_message(response)) return response.raw logger.error(Utility.assemble_response_from_log_message(response)) response.raise_for_status()
def _generate_playlist_m3u8_static_track_url(cls, track_information, **kwargs): channel_number = kwargs['channel_number'] playlist_protocol = kwargs['playlist_protocol'] username = Configuration.get_configuration_parameter( 'CRYSTALCLEAR_USERNAME') password = SecurityManager.decrypt_password( Configuration.get_configuration_parameter( 'CRYSTALCLEAR_PASSWORD')).decode() track_information.append('{0}{1}{2}/{3}/{4}{5}\n'.format( ProvidersController.get_provider_map_class( cls._provider_name).constants_class().BASE_URL, 'live/' if playlist_protocol == 'hls' else '', username, password, channel_number, '.m3u8' if playlist_protocol == 'hls' else ''))
def start_proxy( cls, configuration_file_path, optional_settings_file_path, db_file_path, log_file_path, recordings_directory_path, certificate_file_path, key_file_path, ): Configuration.set_configuration_file_path(configuration_file_path) OptionalSettings.set_optional_settings_file_path( optional_settings_file_path) Database.set_database_file_path(db_file_path) Logging.set_log_file_path(log_file_path) PVR.set_recordings_directory_path(recordings_directory_path) SecurityManager.set_certificate_file_path(certificate_file_path) SecurityManager.set_key_file_path(key_file_path) ProvidersController.initialize() OptionalSettings.read_optional_settings_file() Database.initialize() SecurityManager.initialize() Configuration.read_configuration_file() CacheManager.initialize() HTMLTemplateEngine.initialize() HTTPRequestHandler.initialize() PVR.initialize() Configuration.start_configuration_file_watchdog_observer() OptionalSettings.start_optional_settings_file_watchdog_observer() Logging.start_logging_configuration_file_watchdog_observer() cls.start_http_server() cls.start_https_server() PVR.start() while not cls._shutdown_proxy_event.is_set(): if cls._http_server_thread: cls._http_server_thread.join() if cls._https_server_thread: cls._https_server_thread.join() cls._shutdown_proxy_event.wait(0.5) Configuration.join_configuration_file_watchdog_observer() OptionalSettings.join_optional_settings_file_watchdog_observer() Logging.join_logging_configuration_file_watchdog_observer()
def _generate_playlist_m3u8_static_track_url(cls, track_information, **kwargs): channel_number = kwargs['channel_number'] playlist_protocol = kwargs['playlist_protocol'] url = Configuration.get_configuration_parameter('{0}_URL'.format(cls._provider_name.upper())) username = Configuration.get_configuration_parameter('{0}_USERNAME'.format(cls._provider_name.upper())) password = SecurityManager.decrypt_password( Configuration.get_configuration_parameter('{0}_PASSWORD'.format(cls._provider_name.upper()))).decode() track_information.append( '{0}{1}{2}/{3}/{4}{5}\n'.format( url, 'live/' if playlist_protocol == 'hls' else '', username, password, channel_number, '.m3u8' if playlist_protocol == 'hls' else '.ts'))
def process_configuration_file_updates(cls): with cls._lock.writer_lock: message_to_log = [] purge_http_sessions = False restart_http_server = False restart_https_server = False # <editor-fold desc="Detect and handle SERVER_PASSWORD change"> if cls._configuration[ 'SERVER_PASSWORD'] != cls._previous_configuration[ 'SERVER_PASSWORD']: purge_http_sessions = True message_to_log.append( 'Detected a change in the password option in the [Server] section\n' 'Old value => {0}\n' 'New value => {1}\n'.format( cls._previous_configuration['SERVER_PASSWORD'], cls._configuration['SERVER_PASSWORD'])) # </editor-fold> # <editor-fold desc="Detect and handle SERVER_HOSTNAME_<LOOPBACK,PRIVATE,PUBLIC> change"> loopback_hostname_updated = False private_hostname_updated = False public_hostname_updated = False if cls._configuration['SERVER_HOSTNAME_LOOPBACK'] != \ cls._previous_configuration['SERVER_HOSTNAME_LOOPBACK']: loopback_hostname_updated = True message_to_log.append( 'Detected a change in the loopback option in the [Hostnames] section\n' 'Old value => {0}\n' 'New value => {1}\n'.format( cls. _previous_configuration['SERVER_HOSTNAME_LOOPBACK'], cls._configuration['SERVER_HOSTNAME_LOOPBACK'])) if cls._configuration[ 'SERVER_HOSTNAME_PRIVATE'] != cls._previous_configuration[ 'SERVER_HOSTNAME_PRIVATE']: private_hostname_updated = True message_to_log.append( 'Detected a change in the private option in the [Hostnames] section\n' 'Old value => {0}\n' 'New value => {1}\n'.format( cls._previous_configuration['SERVER_HOSTNAME_PRIVATE'], cls._configuration['SERVER_HOSTNAME_PRIVATE'])) if cls._configuration[ 'SERVER_HOSTNAME_PUBLIC'] != cls._previous_configuration[ 'SERVER_HOSTNAME_PUBLIC']: public_hostname_updated = True message_to_log.append( 'Detected a change in the public option in the [Hostnames] section\n' 'Old value => {0}\n' 'New value => {1}\n'.format( cls._previous_configuration['SERVER_HOSTNAME_PUBLIC'], cls._configuration['SERVER_HOSTNAME_PUBLIC'])) if loopback_hostname_updated or private_hostname_updated or public_hostname_updated: restart_https_server = True # </editor-fold> # <editor-fold desc="Detect and handle SERVER_HTTP_PORT change"> if cls._configuration[ 'SERVER_HTTP_PORT'] != cls._previous_configuration[ 'SERVER_HTTP_PORT']: restart_http_server = True message_to_log.append( 'Detected a change in the http option in the [Ports] section\n' 'Old value => {0}\n' 'New value => {1}\n'.format( cls._previous_configuration['SERVER_HTTP_PORT'], cls._configuration['SERVER_HTTP_PORT'])) # </editor-fold> # <editor-fold desc="Detect and handle SERVER_HTTPS_PORT change"> if cls._configuration[ 'SERVER_HTTPS_PORT'] != cls._previous_configuration[ 'SERVER_HTTPS_PORT']: restart_https_server = True message_to_log.append( 'Detected a change in the https option in the [Ports] section\n' 'Old value => {0}\n' 'New value => {1}\n'.format( cls._previous_configuration['SERVER_HTTPS_PORT'], cls._configuration['SERVER_HTTPS_PORT'])) # </editor-fold> if purge_http_sessions: from iptv_proxy.http_server import HTTPRequestHandler message_to_log.append( 'Action => Purge all user HTTP/S sessions') with Database.get_write_lock(): db_session = Database.create_session() try: HTTPRequestHandler.purge_http_sessions(db_session) db_session.commit() except Exception: (type_, value_, traceback_) = sys.exc_info() logger.error('\n'.join( traceback.format_exception(type_, value_, traceback_))) db_session.rollback() finally: db_session.close() if restart_http_server: from iptv_proxy.controller import Controller message_to_log.append('Action => Restart HTTP server') Controller.shutdown_http_server() Controller.start_http_server() if restart_https_server: from iptv_proxy.security import SecurityManager message_to_log.append('Action => Restart HTTPS server') if SecurityManager.get_auto_generate_self_signed_certificate(): SecurityManager.generate_self_signed_certificate() from iptv_proxy.controller import Controller Controller.shutdown_https_server() Controller.start_https_server() if message_to_log: logger.debug('\n'.join(message_to_log)) for provider_name in sorted( ProvidersController.get_providers_map_class()): ProvidersController.get_provider_map_class( provider_name).configuration_class( ).process_configuration_file_updates( cls._configuration, cls._previous_configuration)
def _refresh_session(cls): requests_session = requests.Session() if Configuration.get_configuration_parameter( 'SMOOTHSTREAMS_SERVICE') == 'viewmmasr': url = 'https://www.mma-tv.net/loginForm.php' else: url = 'https://auth.smoothstreams.tv/hash_api.php' username = Configuration.get_configuration_parameter( 'SMOOTHSTREAMS_USERNAME') password = SecurityManager.decrypt_password( Configuration.get_configuration_parameter( 'SMOOTHSTREAMS_PASSWORD')).decode() site = Configuration.get_configuration_parameter( 'SMOOTHSTREAMS_SERVICE') logger.debug('Retrieving SmoothStreams authorization token\n' 'URL => {0}\n' ' Parameters\n' ' username => {0}\n' ' password => {1}\n' ' site => {2}'.format(url, username, '\u2022' * len(password), site)) response = Utility.make_http_request( requests_session.get, url, params={ 'username': username, 'password': password, 'site': site }, headers=requests_session.headers, cookies=requests_session.cookies.get_dict()) response_status_code = response.status_code if response_status_code != requests.codes.OK and response_status_code != requests.codes.NOT_FOUND: logger.error(Utility.assemble_response_from_log_message(response)) response.raise_for_status() logger.trace( Utility.assemble_response_from_log_message(response, is_content_json=True, do_print_content=True)) authorization_token_response = response.json() session = {} if 'code' in authorization_token_response: if authorization_token_response['code'] == '0': logger.error( 'Failed to retrieve SmoothStreams authorization token\n' 'Error => {0}'.format( authorization_token_response['error'])) elif authorization_token_response['code'] == '1': session['authorization_token'] = authorization_token_response[ 'hash'] session['expires_on'] = datetime.now(pytz.utc) + timedelta( seconds=(authorization_token_response['valid'] * 60)) session['requests_session'] = requests_session logger.info('Retrieved SmoothStreams authorization token\n' 'Hash => {0}\n' 'Expires On => {1}'.format( session['authorization_token'], session['expires_on'].astimezone( tzlocal.get_localzone()).strftime( '%Y-%m-%d %H:%M:%S%z'))) else: logger.error( 'Failed to retrieve SmoothStreams authorization token\n' 'Error => JSON response contains no [\'code\'] field') if response_status_code != requests.codes.OK: response.raise_for_status() return session
def download_ts_file( cls, client_ip_address, client_uuid, requested_path, requested_query_string_parameters, ): authorization_token = requested_query_string_parameters.get( 'authorization_token') channel_number = requested_query_string_parameters.get( 'channel_number') hostname = requested_query_string_parameters.get('hostname') leaf_directory = requested_query_string_parameters.get( 'leaf_directory') port = requested_query_string_parameters.get('port') scheme = requested_query_string_parameters.get('scheme') IPTVProxy.refresh_serviceable_clients(client_uuid, client_ip_address) IPTVProxy.set_serviceable_client_parameter( client_uuid, 'last_request_date_time_in_utc', datetime.now(pytz.utc)) username = Configuration.get_configuration_parameter( '{0}_USERNAME'.format(cls._provider_name.upper())) password = SecurityManager.decrypt_password( Configuration.get_configuration_parameter('{0}_PASSWORD'.format( cls._provider_name.upper()))).decode() requests_session = requests.Session() target_url = '{0}://{1}{2}/hls{3}{4}/{5}/{6}/{7}/{8}{9}'.format( scheme, hostname, port, 'r' if authorization_token else '', '/{0}'.format(authorization_token) if authorization_token else '', username, password, channel_number, leaf_directory, re.sub(r'(/.*)?(/.*\.ts)', r'\2', requested_path), ) logger.debug( 'Proxying request\n' 'Source IP => %s\n' 'Requested path => %s\n' ' Parameters\n' ' channel_number => %s\n' ' client_uuid => %s\n' ' hostname => %s\n' ' port => %s\n' ' scheme => %s\n' 'Target path => %s', client_ip_address, requested_path, channel_number, client_uuid, hostname, port, scheme, target_url, ) response = Utility.make_http_request( requests_session.get, target_url, headers=requests_session.headers, cookies=requests_session.cookies.get_dict(), ) if response.status_code == requests.codes.OK: logger.trace( Utility.assemble_response_from_log_message( response, is_content_binary=True)) IPTVProxy.set_serviceable_client_parameter( client_uuid, 'last_requested_ts_file_path', re.sub(r'(/.*)?(/.*\.ts)', r'\2', requested_path)[1:], ) return response.content logger.error(Utility.assemble_response_from_log_message(response)) response.raise_for_status()
def download_playlist_m3u8( cls, client_ip_address, client_uuid, requested_path, requested_query_string_parameters, ): channel_number = requested_query_string_parameters.get( 'channel_number') http_token = requested_query_string_parameters.get('http_token') protocol = requested_query_string_parameters.get('protocol') IPTVProxy.refresh_serviceable_clients(client_uuid, client_ip_address) IPTVProxy.set_serviceable_client_parameter( client_uuid, 'last_request_date_time_in_utc', datetime.now(pytz.utc)) IPTVProxy.set_serviceable_client_parameter( client_uuid, 'last_requested_channel_number', channel_number) url = Configuration.get_configuration_parameter('{0}_URL'.format( cls._provider_name.upper())) username = Configuration.get_configuration_parameter( '{0}_USERNAME'.format(cls._provider_name.upper())) password = SecurityManager.decrypt_password( Configuration.get_configuration_parameter('{0}_PASSWORD'.format( cls._provider_name.upper()))).decode() if protocol == 'hls': requests_session = requests.Session() target_url = '{0}live/{1}/{2}/{3}.m3u8'.format( url, username, password, channel_number) logger.debug( 'Proxying request\n' 'Source IP => %s\n' 'Requested path => %s\n' ' Parameters\n' ' channel_number => %s\n' ' client_uuid => %s\n' ' protocol => %s\n' 'Target path => %s', client_ip_address, requested_path, channel_number, client_uuid, protocol, target_url, ) response = Utility.make_http_request( requests_session.get, target_url, headers=requests_session.headers, cookies=requests_session.cookies.get_dict(), ) if response.status_code == requests.codes.OK: logger.trace( Utility.assemble_response_from_log_message( response, is_content_text=True, do_print_content=True)) with cls._do_reduce_hls_stream_delay_lock.reader_lock: if cls._do_reduce_hls_stream_delay: chunks_m3u8 = cls._reduce_hls_stream_delay( response.text, client_uuid, channel_number, number_of_segments_to_keep=2, ) else: chunks_m3u8 = response.text parsed_url = urllib.parse.urlparse(response.request.url) scheme = parsed_url.scheme hostname = parsed_url.hostname port = (':{0}'.format(parsed_url.port) if parsed_url.port is not None else '') return re.sub( r'/hls/(.*)/(.*)/(.*)/(.*)/(.*).ts', r'\5.ts?' 'authorization_token=&' 'channel_number={0}&' 'client_uuid={1}&' 'hostname={2}&' 'http_token={3}&' r'leaf_directory=\4&' 'port={4}&' 'scheme={5}'.format( channel_number, client_uuid, urllib.parse.quote(hostname), urllib.parse.quote(http_token) if http_token else '', urllib.parse.quote(port), scheme, ), chunks_m3u8, ) elif response.status_code == requests.codes.FOUND: logger.trace( Utility.assemble_response_from_log_message( response, is_content_text=False, do_print_content=False)) parsed_url = urllib.parse.urlparse( response.headers['Location']) scheme = parsed_url.scheme hostname = parsed_url.hostname port = (':{0}'.format(parsed_url.port) if parsed_url.port is not None else '') return ('#EXTM3U\n' '#EXT-X-VERSION:3\n' '#EXT-X-STREAM-INF:BANDWIDTH=8388608\n' 'chunks.m3u8?authorization_token={0}&' 'channel_number={1}&' 'client_uuid={2}&' 'hostname={3}&' 'http_token={4}&' 'port={5}&' 'scheme={6}'.format( dict(urllib.parse.parse_qsl( parsed_url.query))['token'], channel_number, client_uuid, urllib.parse.quote(hostname), urllib.parse.quote(http_token) if http_token else '', urllib.parse.quote(port), scheme, )) logger.error(Utility.assemble_response_from_log_message(response)) response.raise_for_status() elif protocol == 'mpegts': provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name) return ('#EXTM3U\n' '#EXTINF:-1 ,{0}\n' '{1}live/{2}/{3}/{4}.ts' ''.format( provider_map_class.epg_class().get_channel_name( int(channel_number)), url, username, password, channel_number, ))
def download_chunks_m3u8( cls, client_ip_address, client_uuid, requested_path, requested_query_string_parameters, ): authorization_token = requested_query_string_parameters.get( 'authorization_token') channel_number = requested_query_string_parameters.get( 'channel_number') client_uuid = requested_query_string_parameters.get('client_uuid') hostname = requested_query_string_parameters.get('hostname') http_token = requested_query_string_parameters.get('http_token') port = requested_query_string_parameters.get('port') scheme = requested_query_string_parameters.get('scheme') IPTVProxy.refresh_serviceable_clients(client_uuid, client_ip_address) IPTVProxy.set_serviceable_client_parameter( client_uuid, 'last_request_date_time_in_utc', datetime.now(pytz.utc)) IPTVProxy.set_serviceable_client_parameter( client_uuid, 'last_requested_channel_number', channel_number) username = Configuration.get_configuration_parameter( '{0}_USERNAME'.format(cls._provider_name.upper())) password = SecurityManager.decrypt_password( Configuration.get_configuration_parameter('{0}_PASSWORD'.format( cls._provider_name.upper()))).decode() requests_session = requests.Session() target_url = '{0}://{1}{2}/live/{3}/{4}/{5}.m3u8'.format( scheme, hostname, port, username, password, channel_number) logger.debug( 'Proxying request\n' 'Source IP => %s\n' 'Requested path => %s\n' ' Parameters\n' ' authorization_token => %s\n' ' channel_number => %s\n' ' client_uuid => %s\n' ' hostname => %s\n' ' port => %s\n' ' scheme => %s\n' 'Target path => %s\n' ' Parameters\n' ' token => %s', client_ip_address, requested_path, authorization_token, channel_number, client_uuid, hostname, port, scheme, target_url, authorization_token, ) response = Utility.make_http_request( requests_session.get, target_url, params={'token': authorization_token}, headers=requests_session.headers, cookies=requests_session.cookies.get_dict(), ) if response.status_code == requests.codes.OK: logger.trace( Utility.assemble_response_from_log_message( response, is_content_text=True, do_print_content=True)) with cls._do_reduce_hls_stream_delay_lock.reader_lock: if cls._do_reduce_hls_stream_delay: chunks_m3u8 = cls._reduce_hls_stream_delay( response.text, client_uuid, channel_number, number_of_segments_to_keep=2, ) else: chunks_m3u8 = response.text return re.sub( r'/hlsr/(.*)/(.*)/(.*)/(.*)/(.*)/(.*).ts', r'\6.ts?' r'authorization_token=\1&' 'channel_number={0}&' 'client_uuid={1}&' 'hostname={2}&' 'http_token={3}&' r'leaf_directory=\5&' 'port={4}&' 'scheme={5}'.format( channel_number, client_uuid, urllib.parse.quote(hostname), urllib.parse.quote(http_token) if http_token else '', urllib.parse.quote(port), scheme, ), chunks_m3u8, ) else: logger.error(Utility.assemble_response_from_log_message(response)) response.raise_for_status()
def download_chunks_m3u8(cls, client_ip_address, client_uuid, requested_path, requested_query_string_parameters): channel_number = requested_query_string_parameters.get( 'channel_number') http_token = requested_query_string_parameters.get('http_token') protocol = requested_query_string_parameters.get('protocol') IPTVProxy.refresh_serviceable_clients(client_uuid, client_ip_address) IPTVProxy.set_serviceable_client_parameter( client_uuid, 'last_request_date_time_in_utc', datetime.now(pytz.utc)) username = Configuration.get_configuration_parameter( '{0}_USERNAME'.format(cls._provider_name.upper())) password = SecurityManager.decrypt_password( Configuration.get_configuration_parameter('{0}_PASSWORD'.format( cls._provider_name.upper()))).decode() if protocol == 'hls': requests_session = requests.Session() target_url = '{0}live/{1}/{2}/{3}.m3u8'.format( ProvidersController.get_provider_map_class( cls._provider_name).constants_class().BASE_URL, username, password, channel_number) logger.debug('Proxying request\n' 'Source IP => {0}\n' 'Requested path => {1}\n' ' Parameters\n' ' channel_number => {2}\n' ' client_uuid => {3}\n' ' protocol => {4}\n' 'Target path => {5}'.format( client_ip_address, requested_path, channel_number, client_uuid, protocol, target_url)) response = Utility.make_http_request( requests_session.get, target_url, headers=requests_session.headers, cookies=requests_session.cookies.get_dict()) if response.status_code == requests.codes.OK: logger.trace( Utility.assemble_response_from_log_message( response, is_content_text=True, do_print_content=True)) with cls._do_reduce_hls_stream_delay_lock.reader_lock: if cls._do_reduce_hls_stream_delay: chunks_m3u8 = cls._reduce_hls_stream_delay( response.text, client_uuid, channel_number, number_of_segments_to_keep=2) else: chunks_m3u8 = response.text IPTVProxy.set_serviceable_client_parameter( client_uuid, 'last_requested_channel_number', channel_number) match = re.search( r'http://(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(:\d+)?', response.request.url) server = match.group(1) port = match.group(2) if len(match.groups()) == 2 else ':80' return re.sub( r'/hlsr/(.*)/(.*)/(.*)/(.*)/(.*)/(.*).ts', r'\6.ts?' r'authorization_token=\1&' 'channel_number={0}&' 'client_uuid={1}&' 'http_token={2}&' r'leaf_directory=\5&' 'port={3}&' 'server={4}'.format( channel_number, client_uuid, urllib.parse.quote(http_token) if http_token else '', urllib.parse.quote(port), urllib.parse.quote(server)), chunks_m3u8) else: logger.error( Utility.assemble_response_from_log_message(response)) response.raise_for_status() elif protocol == 'mpegts': provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name) return '#EXTM3U\n' \ '#EXTINF:-1 ,{0}\n' \ '{1}{2}/{3}/{4}' \ ''.format(provider_map_class.constants_class().BASE_URL, provider_map_class.epg_class().get_channel_name(int(channel_number)), username, password, channel_number)