예제 #1
0
    def db_save_setting(parameter, value):
        """
        Save Setting to DB.

        :param parameter: PARAMETER to match
        :param value: Value to save as Str
        :return: True if saved
        """
        id_query = Settings.select().where(Settings.parameter == parameter)
        if not id_query.exists():
            Settings.create(parameter=parameter)
        setting = id_query.get()
        setting.value = str(value)

        # Handle a BusyError attempting to write to Settings by retrying up to five times.
        n_retries = 0
        max_retries = 5
        while True:
            try:
                setting.save()
                break
            except BusyError as be:
                n_retries += 1
                if n_retries > max_retries:
                    raise be
                sleep_time_secs = 0.1 * n_retries
                time.sleep(sleep_time_secs)
                # Don't log at INFO level or above - these are typically written to
                # OPTECS_LOG_MESSAGES table, adding to database contention.
                logging.debug(f'Trip.save() Try#{n_retries} failed w/BusyError. " +'
                              f'Sleeping {sleep_time_secs} seconds before retrying.')
        logging.debug('Save ' + parameter + ' -> ' + str(value))
        return True
    def test_entry_from_db_is_read(self):
        # Get the current entry, if any, ready to restore at conclusion
        select_q = Settings.select().where(
            Settings.parameter == self.TEST_SETTINGS_PARAMETER_NAME)
        orig_list = json.loads(select_q.get().value)
        self._logger.debug("Orig list = {}".format(orig_list))

        test_value = None
        test_candidates = ('NSCC', 'XYZA', 'XXXX'
                           )  # Unlikely real catch category codes
        for candidate_test_value in test_candidates:
            if candidate_test_value not in orig_list:
                test_value = candidate_test_value
                break

        errFmtStr = "Unexpectedly, every value in test value list ({}) was in orig. list"
        self.assertIsNotNone(test_value, errFmtStr.format(test_candidates))
        self._logger.info("Adding {} to value field.".format(test_value))

        # Add a catch category code to the db entry
        test_list = orig_list.copy()
        test_list.append(test_value)
        test_list_as_json = json.dumps(test_list)
        fr_update = Settings.update(value=test_list_as_json).where(
            Settings.parameter == self.TEST_SETTINGS_PARAMETER_NAME)
        fr_update.execute()

        # Test that newly instantiated class returns list with new entry. Three parts:

        # 1. Check that the db has the right updated list
        fr_query = Settings.select().where(
            Settings.parameter == self.TEST_SETTINGS_PARAMETER_NAME)
        updated_list = json.loads(fr_query.get().value)
        self.assertEqual(test_list, updated_list)
        self._logger.debug("updated_list = {}".format(test_list))
        self.assertIsNotNone(updated_list)

        # 2. Verify that the pre-existing frequent catch category code does NOT get updated value -
        #   that it doesn't do a re-pull from the db on every get of its property
        self.assertNotIn(test_value, self.tfcc.catch_category_codes)

        # 3. Instantiate a new copy of frequent catch_category_codes and verify it DOES have the
        #   new value in the list.
        newtfcc = TrawlFrequentCatchCategories(
            self.TEST_SETTINGS_PARAMETER_NAME)
        self.assertIn(test_value, newtfcc.catch_category_codes)
 def getset_setting(parm_name, default_val):
     """ Get parm_name setting from SETTINGS table.
         If setting not in SETTINGS, use default_val.
         Side-effect: also add default_val to SETTINGS table.
     """
     fr_query = Settings.select().where(Settings.parameter == parm_name)
     if not fr_query.exists():
         Settings.create(parameter=parm_name, value=default_val)
     return fr_query.get().value
    def __init__(self, db):
        super().__init__()
        self._logger = logging.getLogger(__name__)

        self._db = db

        # These data will also get saved into (new) Trips
        cs_query = Settings.select().where(Settings.parameter == 'catch_share')
        if not cs_query.exists():
            Settings.create(parameter='catch_share', value='TRUE')
        self._catchshare = cs_query.get()

        gt_query = Settings.select().where(Settings.parameter == 'gear_type')
        if not gt_query.exists():
            Settings.create(parameter='gear_type', value='TRUE')
        self._geartype_trawl_default = gt_query.get()

        self._users = ObserverUsers()

        self._trips = ObserverTrip()
        self._hauls = Hauls(db=db)
        self._sets = Sets(db=db)
        self._catches = ObserverCatches(db=db)

        self._current_cc = None

        self._current_cc_name = ""  # for display
        self._current_spec_name = ""  # for display

        fr_query = Settings.select().where(Settings.parameter == 'first_run')
        if not fr_query.exists():
            Settings.create(parameter='first_run', value='TRUE')
        self._firstrun = fr_query.get()

        cu_query = Settings.select().where(Settings.parameter == 'current_user')
        if not cu_query.exists():
            Settings.create(parameter='current_user')
        self._current_user = cu_query.get()

        cu_query = Settings.select().where(Settings.parameter == 'current_user_id')
        if not cu_query.exists():
            Settings.create(parameter='current_user_id')
        self._current_user_id = cu_query.get()

        # Type max depth as integer
        self._trawl_max_depth_fathoms = int(self.getset_setting(
            'trawl_max_depth_fathoms',
            DefaultDefaultSettings.trawl_max_depth_fathoms))
        self.trawlMaxDepthFathomsChanged.emit(self._trawl_max_depth_fathoms)

        # Confirmation-required basket weight, typed as integer
        self._trawl_confirm_basket_weight_lbs = int(self.getset_setting(
            'trawl_confirm_basket_weight_lbs',
            DefaultDefaultSettings.trawl_confirm_basket_weight_lbs))
        self.trawlConfirmBasketWeightLbsChanged.emit(self._trawl_confirm_basket_weight_lbs)

        # Max basket weight as integer, typed as integer
        self._trawl_max_basket_weight_lbs = int(self.getset_setting(
            'trawl_max_basket_weight_lbs',
            DefaultDefaultSettings.trawl_max_basket_weight_lbs))
        self.trawlMaxBasketWeightLbsChanged.emit(self._trawl_max_basket_weight_lbs)

        # Minimum and maximum degrees latitude as integer.
        # No emits necessary: this value will not change during a run.
        self._trawl_min_latitude_degrees = int(self.getset_setting(
            'trawl_minimum_latitude_degrees',
            DefaultDefaultSettings.trawl_minimum_latitude_degrees))
        self._trawl_max_latitude_degrees = int(self.getset_setting(
            'trawl_maximum_latitude_degrees',
            DefaultDefaultSettings.trawl_maximum_latitude_degrees))

        # DB Backup Thread
        self._backup_thread = QThread()
        self._backup_worker = None

        self._comments_all = ''
        self._comments_trip = ''
        self._comments_haul = dict()
        self._db_formatted_comments_trip = ''
        self._db_formatted_comments_haul = dict()

        self.currentTripId = ObserverDBUtil.db_load_setting('trip_number')  # Current Trip ID if set
        self.update_comments()

        self._catches.retainedCatchWeightChanged.connect(self.update_wm5_catch_weights)  # ret. catch changes --> WM5 updates
        self._hauls.otcWeightChanged.connect(self.update_wm5_catch_weights)  # otc changes --> WM5 updates