Example #1
0
 def load_instances(self):
     inst_defn_obj = ConfigDefn(self.plugin_path, PLUGIN_INSTANCE_DEFN_FILE, self.config_obj.data, True)
     # determine in the config data whether the instance of this name exists.  It would have a section name = 'name-instance'
     self.instances = self.find_instances()
     for inst in self.instances:
         self.plugin_db.save_instance(self.namespace, inst, '')
         # create a defn with the instance name as the section name. then process it.
         inst_defn_obj.is_instance_defn = False
         for area, area_data in inst_defn_obj.config_defn.items():
             if len(area_data['sections']) != 1:
                 self.logger.error('INSTANCE MUST HAVE ONE AND ONLY ONE SECTION')
                 raise exceptions.CabernetException('plugin defn must have one and only one instance section')
             section = list(area_data['sections'].keys())[0]
             base_section = section.split('_', 1)[0]
             area_data['sections'][base_section + '_' + inst] = area_data['sections'].pop(section)
             if 'label' in self.config_obj.data[base_section + '_' + inst] \
                 and self.config_obj.data[base_section + '_' + inst]['label'] is not None:
                 area_data['sections'][base_section + '_' + inst]['label'] = self.config_obj.data[base_section + '_' + inst]['label']
             inst_defn_obj.save_defn_to_db()
             
             default_config = inst_defn_obj.get_default_config()
             self.config_obj.merge_config(default_config)
             inst_defn_obj.call_oninit(self.config_obj)
             self.config_obj.defn_json.merge_defn_obj(inst_defn_obj)
             for area, area_data in inst_defn_obj.config_defn.items():
                 for section, section_data in area_data['sections'].items():
                     for setting in section_data['settings'].keys():
                         new_value = self.config_obj.fix_value_type(
                             section, setting, self.config_obj.data[section][setting])
                         self.config_obj.data[section][setting] = new_value
     self.db_configdefn.add_config(self.config_obj.data)
Example #2
0
    def __init__(self, _locast_inst):
        self.config_obj = _locast_inst.config_obj
        config_section = _locast_inst.config_section
        self.zipcode = self.config_obj.data[config_section][
            "overrides-zipcode"]
        self.latitude = self.config_obj.data[config_section][
            "overrides-latitude"]
        self.longitude = self.config_obj.data[config_section][
            "overrides-longitude"]
        self.dma = None
        self.city = None
        self.active = None
        self.has_dma_changed = False

        if self.find_location():
            self.logger.debug("Got location as {} - DMA {}".format(
                self.city, self.dma))
        else:
            raise exceptions.CabernetException(
                "Unable to retrieve DMA location")

        # Check that Locast reports this market is currently active and available.
        if not self.active:
            self.logger.error(
                "Locast reports that this DMA/Market area is not currently active!"
            )
            raise exceptions.CabernetException(
                "Locast indicates DMA location not active")
        if 'dma' in self.config_obj.data[config_section] \
                and self.config_obj.data[config_section]['dma'] \
                != self.dma:
            self.logger.debug(
                'DMA has changed, purging old DMA data for this instance')
            self.has_dma_changed = True
        # update config file with DMA and City
        self.config_obj.write(config_section, 'dma', self.dma)
        self.config_obj.write(config_section, 'city', self.city)
Example #3
0
    def login(self):
        if not self.username:
            return None
        if not self.password:
            return None
        login_invalid = self.config_obj.data[self.section]['login-invalid']
        if login_invalid is not None:
            delta_secs = time.time() - login_invalid
            # if over 1hr 30 min, then retry login
            if delta_secs < 5400:
                self.logger.error(
                    '{} Unable to login due to invalid logins.  Clear config entry login_invalid to try again'
                    .format(self.section))
                raise exceptions.CabernetException('Locast Login Failed')
            else:
                self.logger.info(
                    '{} Resetting invalid logins config value and retrying login to Locast'
                    .format(self.section))
                self.config_obj.write(self.section, 'login-invalid', "")

        if self.validate_user(True):
            self.logger.info('Reusing Locast token [{}]'.format(self.section))
            return True

        self.logger.info('Logging into Locast [{}]'.format(self.section))
        self.token = self.get_token()
        if not self.token:
            self.logger.error(
                'Invalid Locast Login Credentials. Disabling instance')
            current_time = str(int(time.time()))
            self.config_obj.write(self.section, 'login-invalid', current_time)
            raise exceptions.CabernetException("Locast Login Failed")
        else:
            self.config_obj.write(self.section, 'login-token', self.token)

        return self.validate_user(False)
Example #4
0
def merge_dict(d1, d2, override=False, ignore_conflicts=False):
    for key in d2:
        if key in d1:
            if isinstance(d1[key], dict) and isinstance(d2[key], dict):
                merge_dict(d1[key], d2[key], override, ignore_conflicts)
            elif d1[key] == d2[key]:
                pass
            elif override:
                d1[key] = d2[key]
            elif not ignore_conflicts:
                raise exceptions.CabernetException(
                    'Conflict when merging dictionaries {}'.format(str(key)))
        else:
            d1[key] = d2[key]
    return d1
Example #5
0
    def get_locast_channels(self):
        channels_url = 'https://api.locastnet.org/api/watch/epg/{}' \
            .format(self.locast_instance.location.dma)
        url_headers = {
            'Content-Type': 'application/json',
            'authorization': 'Bearer {}'.format(self.locast_instance.token),
            'User-agent': constants.DEFAULT_USER_AGENT}
        req = urllib.request.Request(channels_url, headers=url_headers)
        with urllib.request.urlopen(req) as resp:
            ch_json = json.load(resp)

        ch_list = []
        if len(ch_json) == 0:
            self.logger.warning('Locast HTTP Channel Request Failed for instance {}'.format(self.instance))
            raise exceptions.CabernetException('Locast HTTP Channel Request Failed')

        self.logger.info("{}: Found {} stations for DMA {} on instance {}"
            .format(self.locast.name, len(ch_json),
            str(self.locast_instance.location.dma), self.instance))

        for locast_channel in ch_json:
            hd = 0
            ch_id = str(locast_channel['id'])
            ch_callsign = locast_channel['name']
            thumbnail = None
            thumbnail_size = None
            if 'logoUrl' in locast_channel.keys():
                thumbnail = locast_channel['logoUrl']
            elif 'logo226Url' in locast_channel.keys():
                thumbnail = locast_channel['logo226Url']
            if thumbnail is not None:
                thumbnail_size = channels.get_thumbnail_size(thumbnail)
            try:
                if 'videoProperties' in locast_channel['listings'][0]:
                    if 'HD' in locast_channel['listings'][0]['videoProperties']:
                        hd = 1
                    else:
                        hd = 0
            except IndexError:
                pass

            try:
                assert (float(locast_channel['callSign'].split()[0]))
                channel = locast_channel['callSign'].split()[0]
                friendly_name = locast_channel['callSign'].split()[1]
                channel = {
                    'id': ch_id,
                    'enabled': True,
                    'callsign': ch_callsign,
                    'number': channel,
                    'name': friendly_name,
                    'HD': hd,
                    'group_hdtv': self.locast_instance.config_obj.data[self.config_section]['m3u-group_hdtv'],
                    'group_sdtv': self.locast_instance.config_obj.data[self.config_section]['m3u-group_sdtv'],
                    'groups_other': None,  # array list of groups/categories
                    'thumbnail': thumbnail,
                    'thumbnail_size': thumbnail_size
                }
                ch_list.append(channel)
            except ValueError:
                self.logger.warning(
                    '################### CALLSIGN ERROR Channel ignored: {} {}'
                        .format(ch_id, locast_channel['callSign']))
        return ch_list