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 write_configuration_file(cls, configuration): configuration_file_path = cls._configuration_file_path try: configuration_object = ConfigObj( configuration_file_path, file_error=True, interpolation=False, write_empty_values=True, ) server_section = { 'password': configuration['SERVER_PASSWORD'], 'Ports': { 'http': configuration['SERVER_HTTP_PORT'], 'https': configuration['SERVER_HTTPS_PORT'], }, 'Hostnames': { 'loopback': configuration['SERVER_HOSTNAME_LOOPBACK'], 'private': configuration['SERVER_HOSTNAME_PRIVATE'], 'public': configuration['SERVER_HOSTNAME_PUBLIC'], }, } configuration_object['Server'] = server_section for provider_name in sorted( ProvidersController.get_providers_map_class()): provider_section = ( ProvidersController.get_provider_map_class(provider_name). configuration_class().create_section(configuration)) if provider_section: configuration_object[ ProvidersController.get_provider_map_class( provider_name).api_class( ).__name__] = provider_section configuration_object.write() logger.debug( 'Updated configuration file\nConfiguration file path => %s', configuration_file_path, ) except OSError: logger.error( 'Could not open the specified configuration file for writing\n' 'Configuration file path => %s', configuration_file_path, ) raise
def validate_update_configuration_request(cls, configuration): errors = {} # <editor-fold desc="Validate Server options"> if not Utility.is_valid_server_password( configuration['SERVER_PASSWORD']): errors['serverPassword'] = '******' if not Utility.is_valid_loopback_hostname( configuration['SERVER_HOSTNAME_LOOPBACK']): errors['serverHostnameLoopback'] = 'Must be a valid loopback IP address or hostname\n' \ 'Recommended value => {0}'.format(DEFAULT_HOSTNAME_LOOPBACK) if not Utility.is_valid_private_hostname( configuration['SERVER_HOSTNAME_PRIVATE']): if not Utility.is_valid_public_hostname( configuration['SERVER_HOSTNAME_PRIVATE']): private_ip_address = Utility.determine_private_ip_address() errors[ 'serverHostnamePrivate'] = 'Must be a valid private IP address, public IP address, or hostname' if private_ip_address: errors[ 'serverHostnamePrivate'] += '\nRecommended value => {0}'.format( private_ip_address) if not Utility.is_valid_public_hostname( configuration['SERVER_HOSTNAME_PUBLIC']): public_ip_address = Utility.determine_public_ip_address() errors[ 'serverHostnamePublic'] = 'Must be a valid public IP address or hostname' if public_ip_address: errors[ 'serverHostnamePublic'] += '\nRecommended value => {0}'.format( public_ip_address) if not Utility.is_valid_port_number(configuration['SERVER_HTTP_PORT']): errors['serverPort'] = 'Must be a number between 0 and 65535' # </editor-fold> for provider_name in sorted( ProvidersController.get_providers_map_class()): ProvidersController.get_provider_map_class( provider_name).configuration_class( ).validate_update_configuration_request(configuration, errors) return errors
def query_channels_minimal_xmltv(cls, db_session): channel_class = ProvidersController.get_provider_map_class( cls._provider_name).channel_class() return db_session.query( channel_class.minimal_xmltv.label('xmltv')).order_by( channel_class.number).yield_per(1)
def shutdown_proxy(cls): cls._shutdown_proxy_event.set() ProvidersController.terminate() CacheManager.cancel_cleanup_cache_timer() PVR.cancel_start_recording_timer() PVR.stop() if cls._http_server_thread: cls._http_server_thread.stop() if cls._https_server_thread: cls._https_server_thread.stop() Configuration.stop_configuration_file_watchdog_observer() OptionalSettings.stop_optional_settings_file_watchdog_observer() Logging.stop_logging_configuration_file_watchdog_observer()
def query_channels_pickle_in_m3u8_group(cls, db_session, channel_m3u8_group): channel_class = ProvidersController.get_provider_map_class( cls._provider_name).channel_class() return db_session.query(channel_class.pickle).filter( channel_class.m3u8_group == channel_m3u8_group).order_by( channel_class.number).all()
def query_minimum_maximum_channel_numbers(cls, db_session): channel_class = ProvidersController.get_provider_map_class( cls._provider_name).channel_class() return db_session.query( func.min(channel_class.number).label('minimum_channel_number'), func.max( channel_class.number).label('maximum_channel_number')).first()
def query_programs_minimal_xmltv(cls, db_session, program_start_cutoff): program_class = ProvidersController.get_provider_map_class( cls._provider_name).program_class() return db_session.query( program_class.minimal_xmltv.label('xmltv')).filter( program_class.start < program_start_cutoff).order_by( program_class.channel_number, program_class.start).yield_per(1)
def query_programs_pickle_by_channel_xmltv_id_start_stop( cls, db_session, channel_xmltv_id, program_start_cutoff, program_stop_cutoff): program_class = ProvidersController.get_provider_map_class( cls._provider_name).program_class() return db_session.query(program_class.pickle).filter( and_(program_class.channel_xmltv_id == channel_xmltv_id, program_class.start < program_start_cutoff, program_class.stop > program_stop_cutoff)).order_by( program_class.start).all()
def is_valid_service(cls, service): is_valid_service = True provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name) if service not in provider_map_class.constants_class( ).VALID_SERVICE_VALUES: is_valid_service = False return is_valid_service
def is_valid_server(cls, server): is_valid_server = True provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name) if server not in provider_map_class.constants_class( ).VALID_SERVER_VALUES: is_valid_server = False return is_valid_server
def is_valid_playlist_type(cls, playlist_type): is_valid_playlist_type = True provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name) if playlist_type not in provider_map_class.constants_class( ).VALID_PLAYLIST_TYPE_VALUES: is_valid_playlist_type = False return is_valid_playlist_type
def is_valid_playlist_protocol(cls, playlist_protocol): is_valid_playlist_protocol = True provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name) if playlist_protocol not in provider_map_class.constants_class( ).VALID_PLAYLIST_PROTOCOL_VALUES: is_valid_playlist_protocol = False return is_valid_playlist_protocol
def create_validate_patch_request_body_schema(cls): provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name) provider_configuration_schema = ( provider_map_class.configuration_class().get_configuration_schema( )) validate_patch_request_body_schema = {} required = {'required': True} validate_patch_request_body_schema['{0}_enabled'.format( cls._provider_name)] = required if 'service' in provider_configuration_schema['Provider']: validate_patch_request_body_schema['{0}_service'.format( cls._provider_name)] = required if 'server' in provider_configuration_schema['Provider']: validate_patch_request_body_schema['{0}_server'.format( cls._provider_name)] = required if 'url' in provider_configuration_schema['Provider']: validate_patch_request_body_schema['{0}_url'.format( cls._provider_name)] = required if 'username' in provider_configuration_schema['Provider']: validate_patch_request_body_schema['{0}_username'.format( cls._provider_name)] = required if 'password' in provider_configuration_schema['Provider']: validate_patch_request_body_schema['{0}_password'.format( cls._provider_name)] = required if 'Playlist' in provider_configuration_schema: if 'protocol' in provider_configuration_schema['Playlist']: validate_patch_request_body_schema[ '{0}_playlist_protocol'.format( cls._provider_name)] = required if 'type' in provider_configuration_schema['Playlist']: validate_patch_request_body_schema['{0}_playlist_type'.format( cls._provider_name)] = required if 'EPG' in provider_configuration_schema: if 'source' in provider_configuration_schema['EPG']: validate_patch_request_body_schema['{0}_epg_source'.format( cls._provider_name)] = required if 'url' in provider_configuration_schema['EPG']: validate_patch_request_body_schema['{0}_epg_url'.format( cls._provider_name)] = required return validate_patch_request_body_schema
def is_valid_epg_source(cls, epg_source): is_valid_epg_source = True provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name) if epg_source not in provider_map_class.constants_class( ).VALID_EPG_SOURCE_VALUES: is_valid_epg_source = False return is_valid_epg_source
def create_patch_request_update_configuration_request(cls, request_body): provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name) provider_configuration_schema = provider_map_class.configuration_class( ).get_configuration_schema() configuration_parameter_name_prefix = cls._provider_name.upper() update_configuration_request = {} attributes = request_body['data']['attributes'] if attributes['{0}_enabled'.format(cls._provider_name)]: if 'service' in provider_configuration_schema['Provider']: update_configuration_request['{0}_SERVICE'.format(configuration_parameter_name_prefix)] = \ attributes['{0}_service'.format(cls._provider_name)].lower() if 'server' in provider_configuration_schema['Provider']: update_configuration_request['{0}_SERVER'.format(configuration_parameter_name_prefix)] = \ attributes['{0}_server'.format(cls._provider_name)].lower() if 'url' in provider_configuration_schema['Provider']: update_configuration_request['{0}_URL'.format(configuration_parameter_name_prefix)] = \ attributes['{0}_url'.format(cls._provider_name)].lower() if 'username' in provider_configuration_schema['Provider']: update_configuration_request['{0}_USERNAME'.format(configuration_parameter_name_prefix)] = \ attributes['{0}_username'.format(cls._provider_name)] if 'password' in provider_configuration_schema['Provider']: update_configuration_request['{0}_PASSWORD'.format(configuration_parameter_name_prefix)] = \ attributes['{0}_password'.format(cls._provider_name)] if 'Playlist' in provider_configuration_schema: if 'protocol' in provider_configuration_schema['Playlist']: update_configuration_request['{0}_PLAYLIST_PROTOCOL'.format( configuration_parameter_name_prefix)] = \ attributes['{0}_playlist_protocol'.format(cls._provider_name)].lower() if 'type' in provider_configuration_schema['Playlist']: update_configuration_request['{0}_PLAYLIST_TYPE'.format(configuration_parameter_name_prefix)] = \ attributes['{0}_playlist_type'.format(cls._provider_name)].lower() if 'EPG' in provider_configuration_schema: if 'source' in provider_configuration_schema['EPG']: update_configuration_request['{0}_EPG_SOURCE'.format(configuration_parameter_name_prefix)] = \ attributes['{0}_epg_source'.format(cls._provider_name)].lower() if 'url' in provider_configuration_schema['EPG']: update_configuration_request['{0}_EPG_URL'.format(configuration_parameter_name_prefix)] = \ attributes['{0}_epg_url'.format(cls._provider_name)].lower() return update_configuration_request
def _render_iptv_proxy_script_configuration_update_template(self): iptv_proxy_script_configuration_update_template = self._environment.get_template( 'iptv_proxy_script_configuration_update.js') iptv_proxy_script_configuration_update = iptv_proxy_script_configuration_update_template.render( ).split('\n') for (provider_map_class ) in ProvidersController.get_providers_map_class().values(): iptv_proxy_script_configuration_update.extend( provider_map_class.html_template_engine_class( ).render_iptv_proxy_script_configuration_update_template( self._environment)) return '\n'.join(sorted(iptv_proxy_script_configuration_update))[:-1]
def _render_configuration_providers_templates(self, active_providers_map_class): providers_html = {} for (provider_map_class ) in ProvidersController.get_providers_map_class().values(): providers_html.update( provider_map_class.html_template_engine_class( ).render_configuration_template(self._environment, self._configuration, active_providers_map_class)) return '\n'.join([ providers_html[provider_name] for provider_name in sorted(providers_html) ])
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 create_get_request_response_content(cls, configuration): provider_map_class = ProvidersController.get_provider_map_class(cls._provider_name) provider_configuration_schema = provider_map_class.configuration_class().get_configuration_schema() configuration_parameter_name_prefix = cls._provider_name.upper() provider_configuration = {} if 'service' in provider_configuration_schema['Provider']: provider_configuration['{0}_service'.format(cls._provider_name)] = configuration['{0}_SERVICE'.format( configuration_parameter_name_prefix)] if 'server' in provider_configuration_schema['Provider']: provider_configuration['{0}_server'.format(cls._provider_name)] = configuration['{0}_SERVER'.format( configuration_parameter_name_prefix)] if 'username' in provider_configuration_schema['Provider']: provider_configuration['{0}_username'.format(cls._provider_name)] = configuration['{0}_USERNAME'.format( configuration_parameter_name_prefix)] if 'password' in provider_configuration_schema['Provider']: provider_configuration['{0}_password'.format(cls._provider_name)] = configuration['{0}_PASSWORD'.format( configuration_parameter_name_prefix)] if 'Playlist' in provider_configuration_schema: if 'protocol' in provider_configuration_schema['Playlist']: provider_configuration['{0}_playlist_protocol'.format(cls._provider_name)] = \ configuration['{0}_PLAYLIST_PROTOCOL'.format(configuration_parameter_name_prefix)] if 'type' in provider_configuration_schema['Playlist']: provider_configuration['{0}_playlist_type'.format(cls._provider_name)] = \ configuration['{0}_PLAYLIST_TYPE'.format(configuration_parameter_name_prefix)] if 'EPG' in provider_configuration_schema: if 'source' in provider_configuration_schema['EPG']: provider_configuration['{0}_epg_source'.format(cls._provider_name)] = \ configuration['{0}_EPG_SOURCE'.format(configuration_parameter_name_prefix)] if 'url' in provider_configuration_schema['EPG']: if configuration['{0}_EPG_URL'.format(configuration_parameter_name_prefix)] is not None: provider_configuration['{0}_epg_url'.format(cls._provider_name)] = \ configuration['{0}_EPG_URL'.format(configuration_parameter_name_prefix)] else: provider_configuration['{0}_epg_url'.format(cls._provider_name)] = '' return provider_configuration
def render_iptv_proxy_script_configuration_init_template(cls, environment): provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name) iptv_proxy_script_configuration_xstream_provider_init_template = environment.get_template( 'iptv_proxy_script_configuration_xstream_provider_init.js') iptv_proxy_script_configuration_xstream_provider_init_template_fields = { 'provider_name_camel_case': '{0}{1}'.format( provider_map_class.constants_class().PROVIDER_NAME[0].lower(), provider_map_class.constants_class().PROVIDER_NAME[1:]) } return iptv_proxy_script_configuration_xstream_provider_init_template.render( iptv_proxy_script_configuration_xstream_provider_init_template_fields ).split('\n')
def _render_iptv_proxy_script_configuration_toggle_password_template(self): iptv_proxy_script_configuration_toggle_password_template = self._environment.get_template( 'iptv_proxy_script_configuration_toggle_password.js') iptv_proxy_script_configuration_toggle_password = [ iptv_proxy_script_configuration_toggle_password_template.render() ] for (provider_map_class ) in ProvidersController.get_providers_map_class().values(): iptv_proxy_script_configuration_toggle_password.append( provider_map_class.html_template_engine_class(). render_iptv_proxy_script_configuration_toggle_password_template( self._environment)) return ' else '.join( sorted(iptv_proxy_script_configuration_toggle_password))
def render_iptv_proxy_script_configuration_toggle_password_template( cls, environment ): provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name ) iptv_proxy_script_configuration_provider_toggle_password_template = environment.get_template( 'iptv_proxy_script_configuration_provider_toggle_password.js' ) iptv_proxy_script_configuration_provider_toggle_password_template_fields = { 'provider_name_camel_case': '{0}{1}'.format( provider_map_class.constants_class().PROVIDER_NAME[0].lower(), provider_map_class.constants_class().PROVIDER_NAME[1:], ) } return iptv_proxy_script_configuration_provider_toggle_password_template.render( iptv_proxy_script_configuration_provider_toggle_password_template_fields ).lstrip()
def _render_iptv_proxy_script_template(self, authorization_required, guide_number_of_days, streaming_protocol): iptv_proxy_script_template = self._environment.get_template( 'iptv_proxy_script.js') iptv_proxy_script_template_fields = { 'providers': sorted(ProvidersController.get_providers_map_class()), 'authorization_basic_password': '******'.format( base64.b64encode(':{0}'.format( self._configuration['SERVER_PASSWORD']).encode()).decode()) if authorization_required else '', 'configuration_declarations': self._render_iptv_proxy_script_configuration_declarations_template( ), 'configuration_clear': self._render_iptv_proxy_script_configuration_clear_template(), 'configuration_init_declarations': self._render_iptv_proxy_script_configuration_init_template(), 'configuration_reset': self._render_iptv_proxy_script_configuration_reset_template(), 'configuration_toggle_password': self. _render_iptv_proxy_script_configuration_toggle_password_template(), 'configuration_update': self._render_iptv_proxy_script_configuration_update_template(), 'last_selected_guide_number_of_days': guide_number_of_days, 'last_selected_streaming_protocol': streaming_protocol, } return iptv_proxy_script_template.render( iptv_proxy_script_template_fields)
def read_configuration_file(cls, initial_read=True): with cls._lock.writer_lock: cls._backup_configuration() try: configuration_object = ConfigObj(cls._configuration_file_path, file_error=True, indent_type='', interpolation=False, raise_errors=True, write_empty_values=True) configuration_object_md5 = hashlib.md5( '{0}'.format(configuration_object).encode()).hexdigest() configuration = {} providers = [] non_defaultable_error = False error_message_to_log = [] message_to_log = [] password = None hostname_loopback = DEFAULT_HOSTNAME_LOOPBACK hostname_private = None hostname_public = None http_port = None https_port = None # <editor-fold desc="Read Server section"> try: server_section = configuration_object['Server'] try: password = server_section['password'] except KeyError: non_defaultable_error = True error_message_to_log.append( 'Could not find a password option in the [Server] section\n' ) try: server_hostnames_section = server_section['Hostnames'] # <editor-fold desc="Read loopback option"> try: hostname_loopback = server_hostnames_section[ 'loopback'] if not Utility.is_valid_loopback_hostname( hostname_loopback): error_message_to_log.append( 'The loopback option in the [Hostnames] section has an invalid loopback hostname\n' 'Defaulting to {0}\n'.format( DEFAULT_HOSTNAME_LOOPBACK)) except KeyError: hostname_loopback = DEFAULT_HOSTNAME_LOOPBACK error_message_to_log.append( 'The loopback option in the [Hostnames] section is missing\n' 'Defaulting to {0}\n'.format( DEFAULT_HOSTNAME_LOOPBACK)) # </editor-fold> # <editor-fold desc="Read private option"> do_determine_private_ip_address = False try: hostname_private = server_hostnames_section[ 'private'] if not Utility.is_valid_private_hostname( hostname_private): if Utility.is_valid_public_hostname( hostname_private): error_message_to_log.append( 'The private option in the [Hostnames] section has a public IP address\n' ) else: do_determine_private_ip_address = True except KeyError: do_determine_private_ip_address = True # </editor-fold> # <editor-fold desc="Read public option"> do_determine_public_ip_address = False try: hostname_public = server_hostnames_section[ 'public'] if not Utility.is_valid_public_hostname( hostname_public): do_determine_public_ip_address = True except KeyError: do_determine_public_ip_address = True # </editor-fold> except KeyError: error_message_to_log.append( 'Could not find a [Hostnames] section in the [Server] section\n' ) hostname_loopback = DEFAULT_HOSTNAME_LOOPBACK do_determine_private_ip_address = True do_determine_public_ip_address = True if do_determine_private_ip_address: hostname_private = Utility.determine_private_ip_address( ) if hostname_private: error_message_to_log.append( 'The private option in the [Hostnames] section has an invalid private IP address\n' 'Reverting to {0}\n'.format(hostname_private)) if do_determine_public_ip_address: hostname_public = Utility.determine_public_ip_address() if hostname_public: error_message_to_log.append( 'The public option in the [Hostnames] section has an invalid public IP address\n' 'Reverting to {0}\n'.format(hostname_public)) try: server_ports_section = server_section['Ports'] # <editor-fold desc="Read http option"> try: http_port = server_ports_section['http'] if not Utility.is_valid_port_number(http_port): non_defaultable_error = True error_message_to_log.append( 'The http option in the [Ports] section must be a number between 0 and 65535\n' ) except KeyError: non_defaultable_error = True error_message_to_log.append( 'Could not find an http option in the [Ports] section\n' 'The http option in the [Ports] section must be a number between 0 and 65535\n' ) # </editor-fold> # <editor-fold desc="Read https option"> try: https_port = server_ports_section['https'] if not Utility.is_valid_port_number(https_port): non_defaultable_error = True error_message_to_log.append( 'The https option in the [Ports] section must be a number between 0 and 65535\n' ) except KeyError: non_defaultable_error = True error_message_to_log.append( 'Could not find an https option in the [Ports] section\n' 'The https option in the [Ports] section must be a number between 0 and 65535\n' ) # </editor-fold> except KeyError: non_defaultable_error = True error_message_to_log.append( 'Could not find a [Ports] section in the [Server] section\n' ) except KeyError: non_defaultable_error = True error_message_to_log.append( 'Could not find a [Server] section\n') # </editor-fold> if not non_defaultable_error: configuration = { 'SERVER_PASSWORD': password, 'SERVER_HOSTNAME_LOOPBACK': hostname_loopback, 'SERVER_HOSTNAME_PRIVATE': hostname_private, 'SERVER_HOSTNAME_PUBLIC': hostname_public, 'SERVER_HTTP_PORT': http_port, 'SERVER_HTTPS_PORT': https_port } message_to_log = [ '{0}ead configuration file\n' 'Configuration file path => {1}\n\n' 'SERVER_PASSWORD => {2}\n' 'SERVER_HOSTNAME_LOOPBACK => {3}\n' 'SERVER_HOSTNAME_PRIVATE => {4}\n' 'SERVER_HOSTNAME_PUBLIC => {5}\n' 'SERVER_HTTP_PORT => {6}\n' 'SERVER_HTTPS_PORT => {7}'.format( 'R' if initial_read else 'Rer', cls._configuration_file_path, password, hostname_loopback, hostname_private, hostname_public, http_port, https_port) ] for provider_name in sorted( ProvidersController.get_providers_map_class()): ProvidersController.get_provider_map_class( provider_name).configuration_class( ).read_configuration_file(configuration_object, configuration, providers, message_to_log, error_message_to_log) if not non_defaultable_error: logger.info('\n'.join(message_to_log)) cls._set_configuration(configuration) if configuration_object_md5 != hashlib.md5('{0}'.format( configuration_object).encode()).hexdigest(): cls._update_configuration_file(configuration_object) if initial_read: ProvidersController.initialize_providers(providers) if error_message_to_log: error_message_to_log.insert( 0, '{0} configuration file values\n' 'Configuration file path => {1}\n'.format( 'Invalid' if non_defaultable_error else 'Warnings regarding', cls._configuration_file_path)) if initial_read and non_defaultable_error: error_message_to_log.append('Exiting...') elif non_defaultable_error: error_message_to_log.append( 'Configuration file skipped') else: error_message_to_log.append( 'Configuration file processed') logger.error('\n'.join(error_message_to_log)) if initial_read and non_defaultable_error: sys.exit() except OSError: logger.error( 'Could not open the specified configuration file for reading\n' 'Configuration file path => {0}' '{1}'.format(cls._configuration_file_path, '\n\nExiting...' if initial_read else '')) if initial_read: sys.exit() except SyntaxError as e: logger.error('Invalid configuration file syntax\n' 'Configuration file path => {0}\n' '{1}' '{2}'.format( cls._configuration_file_path, '{0}'.format(e), '\n\nExiting...' if initial_read else '')) if initial_read: sys.exit()
def render_configuration_template( cls, environment, configuration, active_providers_map_class ): provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name ) configuration_xstream_provider_template = environment.get_template( 'configuration_xstream_provider.html' ) configuration_xstream_provider_template_fields = dict( provider_name_camel_case='{0}{1}'.format( provider_map_class.constants_class().PROVIDER_NAME[0].lower(), provider_map_class.constants_class().PROVIDER_NAME[1:], ), provider_name_pascal_case=provider_map_class.constants_class().PROVIDER_NAME, configuration_provider_url='', configuration_provider_username='', configuration_provider_password='', configuration_provider_playlist_protocol_hls_selected='', configuration_provider_playlist_protocol_mpegts_selected='', configuration_provider_playlist_type_static_selected='', configuration_provider_playlist_type_dynamic_selected='', configuration_provider_epg_source_provider_selected='', configuration_provider_epg_source_other_selected='', configuration_provider_epg_url='', ) configuration_xstream_provider_template_fields[ 'configuration_provider_active' ] = ( 'checked="checked"' if cls._provider_name in active_providers_map_class else '' ) if '{0}_URL'.format(cls._provider_name.upper()) in configuration: configuration_xstream_provider_template_fields[ 'configuration_provider_url' ] = configuration['{0}_URL'.format(cls._provider_name.upper())] if '{0}_USERNAME'.format(cls._provider_name.upper()) in configuration: configuration_xstream_provider_template_fields[ 'configuration_provider_username' ] = configuration['{0}_USERNAME'.format(cls._provider_name.upper())] if '{0}_PASSWORD'.format(cls._provider_name.upper()) in configuration: configuration_xstream_provider_template_fields[ 'configuration_provider_password' ] = configuration['{0}_PASSWORD'.format(cls._provider_name.upper())] if '{0}_PLAYLIST_PROTOCOL'.format(cls._provider_name.upper()) in configuration: if ( configuration[ '{0}_PLAYLIST_PROTOCOL'.format(cls._provider_name.upper()) ].lower() == 'hls' ): configuration_xstream_provider_template_fields[ 'configuration_provider_playlist_protocol_hls_selected' ] = 'selected="selected" ' elif ( configuration[ '{0}_PLAYLIST_PROTOCOL'.format(cls._provider_name.upper()) ].lower() == 'mpegts' ): configuration_xstream_provider_template_fields[ 'configuration_provider_playlist_protocol_mpegts_selected' ] = 'selected="selected" ' if '{0}_PLAYLIST_TYPE'.format(cls._provider_name.upper()) in configuration: if ( configuration[ '{0}_PLAYLIST_TYPE'.format(cls._provider_name.upper()) ].lower() == 'dynamic' ): configuration_xstream_provider_template_fields[ 'configuration_provider_playlist_type_dynamic_selected' ] = 'selected="selected" ' elif ( configuration[ '{0}_PLAYLIST_TYPE'.format(cls._provider_name.upper()) ].lower() == 'static' ): configuration_xstream_provider_template_fields[ 'configuration_provider_playlist_type_static_selected' ] = 'selected="selected" ' if '{0}_EPG_SOURCE'.format(cls._provider_name.upper()) in configuration: if ( configuration[ '{0}_EPG_SOURCE'.format(cls._provider_name.upper()) ].lower() == 'other' ): configuration_xstream_provider_template_fields[ 'configuration_provider_epg_source_other_selected' ] = 'selected="selected" ' elif ( configuration[ '{0}_EPG_SOURCE'.format(cls._provider_name.upper()) ].lower() == cls._provider_name ): configuration_xstream_provider_template_fields[ 'configuration_provider_epg_source_provider_selected' ] = 'selected="selected" ' if '{0}_EPG_URL'.format(cls._provider_name.upper()) in configuration: if ( configuration['{0}_EPG_URL'.format(cls._provider_name.upper())] is not None ): configuration_xstream_provider_template_fields[ 'configuration_provider_epg_url' ] = configuration['{0}_EPG_URL'.format(cls._provider_name.upper())] return { provider_map_class.constants_class().PROVIDER_NAME: configuration_xstream_provider_template.render( configuration_xstream_provider_template_fields ) }
def render_configuration_template(cls, environment, configuration, active_providers_map_class): provider_map_class = ProvidersController.get_provider_map_class( cls._provider_name) configuration_smoothstreams_template = environment.get_template( 'configuration_smoothstreams.html') configuration_smoothstreams_template_fields = { 'configuration_smoothstreams_active': 'checked="checked"' if 'smoothstreams' in active_providers_map_class else '', 'configuration_view247_selected': '', 'configuration_viewmmasr_selected': '', 'configuration_viewss_selected': '', 'configuration_viewstvn_selected': '', 'configuration_dap_selected': '', 'configuration_deu_selected': '', 'configuration_dna_selected': '', 'configuration_deu_de_selected': '', 'configuration_deu_nl_selected': '', 'configuration_deu_uk_selected': '', 'configuration_dnae_selected': '', 'configuration_dnaw_selected': '', 'configuration_deu_nl1_selected': '', 'configuration_deu_nl2_selected': '', 'configuration_deu_nl3_selected': '', 'configuration_deu_nl4_selected': '', 'configuration_deu_nl5_selected': '', 'configuration_deu_uk1_selected': '', 'configuration_deu_uk2_selected': '', 'configuration_dnae1_selected': '', 'configuration_dnae2_selected': '', 'configuration_dnae3_selected': '', 'configuration_dnae4_selected': '', 'configuration_dnae6_selected': '', 'configuration_dnaw1_selected': '', 'configuration_dnaw2_selected': '', 'configuration_dnaw3_selected': '', 'configuration_dnaw4_selected': '', 'configuration_smoothstreams_username': '', 'configuration_smoothstreams_password': '', 'configuration_smoothstreams_playlist_protocol_hls_selected': '', 'configuration_smoothstreams_playlist_protocol_rtmp_selected': '', 'configuration_smoothstreams_playlist_type_dynamic_selected': '', 'configuration_smoothstreams_playlist_type_static_selected': '', 'configuration_smoothstreams_epg_source_smoothstreams_selected': '', 'configuration_smoothstreams_epg_source_fog_selected': '', 'configuration_smoothstreams_epg_source_other_selected': '', 'configuration_smoothstreams_epg_url': '', } if 'SMOOTHSTREAMS_SERVICE' in configuration: configuration_smoothstreams_template_fields[ 'configuration_{0}_selected'.format( configuration['SMOOTHSTREAMS_SERVICE'].lower( ))] = 'selected="selected" ' if 'SMOOTHSTREAMS_SERVER' in configuration: configuration_smoothstreams_template_fields[ 'configuration_{0}_selected'.format( configuration['SMOOTHSTREAMS_SERVER'].lower().replace( '-', '_'))] = 'selected="selected" ' if 'SMOOTHSTREAMS_USERNAME' in configuration: configuration_smoothstreams_template_fields[ 'configuration_smoothstreams_username'] = configuration[ 'SMOOTHSTREAMS_USERNAME'] if 'SMOOTHSTREAMS_PASSWORD' in configuration: configuration_smoothstreams_template_fields[ 'configuration_smoothstreams_password'] = configuration[ 'SMOOTHSTREAMS_PASSWORD'] if 'SMOOTHSTREAMS_PLAYLIST_PROTOCOL' in configuration: configuration_smoothstreams_template_fields[ 'configuration_smoothstreams_playlist_protocol_{0}_selected'. format(configuration['SMOOTHSTREAMS_PLAYLIST_PROTOCOL'].lower( ))] = 'selected="selected" ' if 'SMOOTHSTREAMS_PLAYLIST_TYPE' in configuration: configuration_smoothstreams_template_fields[ 'configuration_smoothstreams_playlist_type_{0}_selected'. format(configuration['SMOOTHSTREAMS_PLAYLIST_TYPE'].lower() )] = 'selected="selected" ' if 'SMOOTHSTREAMS_EPG_SOURCE' in configuration: configuration_smoothstreams_template_fields[ 'configuration_smoothstreams_epg_source_{0}_selected'.format( configuration['SMOOTHSTREAMS_EPG_SOURCE'].lower( ))] = 'selected="selected" ' if 'SMOOTHSTREAMS_EPG_URL' in configuration: if configuration['SMOOTHSTREAMS_EPG_URL'] is None: configuration_smoothstreams_template_fields[ 'configuration_smoothstreams_epg_url'] = '' else: configuration_smoothstreams_template_fields[ 'configuration_smoothstreams_epg_url'] = configuration[ 'SMOOTHSTREAMS_EPG_URL'] return { provider_map_class.constants_class().PROVIDER_NAME: configuration_smoothstreams_template.render( configuration_smoothstreams_template_fields) }
def process_optional_settings_file_updates(cls): with cls._lock.writer_lock: message_to_log = [] # <editor-fold desc="Detect and handle cache_downloaded_segments change"> if 'cache_downloaded_segments' not in cls._optional_settings: cls._optional_settings['cache_downloaded_segments'] = True if 'cache_downloaded_segments' not in cls._previous_optional_settings: cls._previous_optional_settings[ 'cache_downloaded_segments'] = True if cls._optional_settings['cache_downloaded_segments'] != \ cls._previous_optional_settings['cache_downloaded_segments']: from iptv_proxy.cache import CacheManager message_to_log.append( 'Detected a change in the cache_downloaded_segments setting\n' 'Old value => {0}\n' 'New value => {1}\n'.format( json.dumps(cls._previous_optional_settings[ 'cache_downloaded_segments']), json.dumps( cls._optional_settings['cache_downloaded_segments'] ))) CacheManager.set_do_cache_downloaded_segments( cls._optional_settings['cache_downloaded_segments']) # </editor-fold> # <editor-fold desc="Detect and handle allow_insecure_lan_connections change"> if 'allow_insecure_lan_connections' not in cls._optional_settings: cls._optional_settings['allow_insecure_lan_connections'] = True if 'allow_insecure_lan_connections' not in cls._previous_optional_settings: cls._previous_optional_settings[ 'allow_insecure_lan_connections'] = True if cls._optional_settings['allow_insecure_lan_connections'] != \ cls._previous_optional_settings['allow_insecure_lan_connections']: from iptv_proxy.http_server import HTTPRequestHandler message_to_log.append( 'Detected a change in the allow_insecure_lan_connections setting\n' 'Old value => {0}\n' 'New value => {1}\n'.format( json.dumps(cls._previous_optional_settings[ 'allow_insecure_lan_connections']), json.dumps(cls._optional_settings[ 'allow_insecure_lan_connections']))) HTTPRequestHandler.set_allow_insecure_lan_connections( cls._optional_settings['allow_insecure_lan_connections']) # </editor-fold> # <editor-fold desc="Detect and handle allow_insecure_wan_connections change"> if 'allow_insecure_wan_connections' not in cls._optional_settings: cls._optional_settings[ 'allow_insecure_wan_connections'] = False if 'allow_insecure_wan_connections' not in cls._previous_optional_settings: cls._previous_optional_settings[ 'allow_insecure_wan_connections'] = False if cls._optional_settings['allow_insecure_wan_connections'] != \ cls._previous_optional_settings['allow_insecure_wan_connections']: from iptv_proxy.http_server import HTTPRequestHandler message_to_log.append( 'Detected a change in the allow_insecure_wan_connections setting\n' 'Old value => {0}\n' 'New value => {1}\n'.format( json.dumps(cls._previous_optional_settings[ 'allow_insecure_wan_connections']), json.dumps(cls._optional_settings[ 'allow_insecure_wan_connections']))) HTTPRequestHandler.set_allow_insecure_wan_connections( cls._optional_settings['allow_insecure_wan_connections']) # </editor-fold> # <editor-fold desc="Detect and handle lan_connections_require_credentials change"> if 'lan_connections_require_credentials' not in cls._optional_settings: cls._optional_settings[ 'lan_connections_require_credentials'] = False if 'lan_connections_require_credentials' not in cls._previous_optional_settings: cls._previous_optional_settings[ 'lan_connections_require_credentials'] = False if cls._optional_settings['lan_connections_require_credentials'] != \ cls._previous_optional_settings['lan_connections_require_credentials']: from iptv_proxy.http_server import HTTPRequestHandler message_to_log.append( 'Detected a change in the lan_connections_require_credentials setting\n' 'Old value => {0}\n' 'New value => {1}\n'.format( json.dumps(cls._previous_optional_settings[ 'lan_connections_require_credentials']), json.dumps(cls._optional_settings[ 'lan_connections_require_credentials']))) HTTPRequestHandler.set_lan_connections_require_credentials( cls. _optional_settings['lan_connections_require_credentials']) # </editor-fold> # <editor-fold desc="Detect and handle wan_connections_require_credentials change"> if 'wan_connections_require_credentials' not in cls._optional_settings: cls._optional_settings[ 'wan_connections_require_credentials'] = True if 'wan_connections_require_credentials' not in cls._previous_optional_settings: cls._previous_optional_settings[ 'wan_connections_require_credentials'] = True if cls._optional_settings['wan_connections_require_credentials'] != \ cls._previous_optional_settings['wan_connections_require_credentials']: from iptv_proxy.http_server import HTTPRequestHandler message_to_log.append( 'Detected a change in the wan_connections_require_credentials setting\n' 'Old value => {0}\n' 'New value => {1}\n'.format( json.dumps(cls._previous_optional_settings[ 'wan_connections_require_credentials']), json.dumps(cls._optional_settings[ 'wan_connections_require_credentials']))) HTTPRequestHandler.set_wan_connections_require_credentials( cls. _optional_settings['wan_connections_require_credentials']) # </editor-fold> if message_to_log: message_to_log.append('Action => N/A') logger.debug('\n'.join(message_to_log)) for provider_name in sorted( ProvidersController.get_providers_map_class()): ProvidersController.get_provider_map_class( provider_name).optional_settings_class( ).process_optional_settings_file_updates( cls._optional_settings, cls._previous_optional_settings)
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 query_channels_m3u8_groups(cls, db_session): channel_class = ProvidersController.get_provider_map_class( cls._provider_name).channel_class() return db_session.query( channel_class.m3u8_group).distinct().yield_per(1)