def _search_threaded_stop(self, regexp, filename, iterator, results, search_start): log.debug('Search in {} stopped after {} (time) / {} (clock) s' ''.format(filename, time.time() - search_start[0], time.clock() - search_start[1])) # The number of ongoing threads must be updated in the main thread wx.CallAfter(self.finish_search)
def close(self): if self.is_shown(): log.debug("Destroying alarm id: {}".format(self.alarmid)) self.panel.Destroy() # It's necessary to explicitly unbind the handler, otherwise this # object will not be garbage-collected core_api.bind_to_update_item_text(self._update_info, False)
def close(self): if self.is_shown(): log.debug('Destroying alarm id: {}'.format(self.alarmid)) self.panel.Destroy() # It's necessary to explicitly unbind the handler, otherwise this # object will not be garbage-collected core_api.bind_to_update_item_text(self._update_info, False)
def show(self): log.debug("Appending alarm id: {}".format(self.alarmid)) self.panel = wx.Panel(self.awindow.panel) self.pbox = wx.BoxSizer(wx.VERTICAL) self.panel.SetSizer(self.pbox) self._init_widgets(self.panel) self.awindow.pbox.Add(self.panel, flag=wx.EXPAND)
def redo_database_history(): if _select_database(): log.debug('Simulate redo history') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_redo_tree(no_confirm=True) else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def show(self): log.debug('Appending alarm id: {}'.format(self.alarmid)) self.panel = wx.Panel(self.awindow.panel) self.pbox = wx.BoxSizer(wx.VERTICAL) self.panel.SetSizer(self.pbox) self._init_widgets(self.panel) self.awindow.pbox.Add(self.panel, flag=wx.EXPAND)
def stop(kwargs=None): # kwargs is passed from the binding to core_api.bind_to_exit_app_1 # Do *not* check also if timer.IsRunning(), see also comment [1] global timer if timer: log.debug('Stop simulator') timer.Stop() timer = None
def block(self, block=False, quiet=False): try: self.s = self.q.get(block) except queue.Empty: if not quiet: blocked_databases_event.signal() return False else: log.debug('Block databases') return True
def block(self, block=False, quiet=False): try: self.s = self.q.get(block) except queue.Empty: if not quiet: blocked_databases_event.signal() return False else: log.debug("Block databases") return True
def main(): if wxtrayicon_api: trayicon = BlinkingTrayIcon() wxtrayicon_id = trayicon.ref_id else: wxtrayicon_id = None if Notify and GLib: Notifications(wxtrayicon_id) else: log.debug('PyGobject\'s Notify module is either not installed or a ' 'wrong version')
def start(self): # Do not use directly NextOccurrencesEngine to search for old # occurrences when opening a database, in fact if the database hasn't # been opened for a while and it has _many_ old occurrences to # activate, NextOccurrencesEngine could recurse too many times, # eventually raising a RuntimeError exception # This function can also speed up opening an old database if it has # many occurrences to activate immediately # Search until 2 minutes ago and let NextOccurrencesEngine handle the # rest, so as to make sure not to interfere with its functionality self.whileago = int(time_.time()) - 120 last_search = self.database.get_last_search() if self.whileago > last_search: log.debug('Search old occurrences') # Set the last search in this (main) thread, otherwise # NextOccurrencesEngine would race with this function, and possibly # do the same search, in fact still seeing the old last search # timestamp # Note that saving and closing the database after this point, but # before the search is finished and the old alarms are activated, # would lose all the old alarms; that's why saving must be # prevented while the search is ongoing core_api.bind_to_save_permission_check( self._handle_save_permission_check) self.database.set_last_search(self.whileago) # The "excl" in the name reminds that this time is exclusive, i.e. # only the occurrences strictly greater than the value will then be # activated, even though the search actually finds also those with # time equal to this value self.exclmint = last_search # Use a thread to let the GUI be responsive and possibly abort the # search # Start the thread with a timer to give some time for the # *interface* to finish opening the database, otherwise the # old alarms dialog will appear with a lot of delay and it will be # very hard to restrict the search range or skip the search # altogether # Note that DELAY shouldn't be too long, in fact self.restart and # self.abort are not protected, and if they're called during this # time, they crash because self.search hasn't been assigned yet thread = threading.Timer(self.DELAY, self._continue) thread.name = "organism_old_occurrences_{}".format(self.filename) # Do not set the thread as a daemon, it's better to properly handle # closing the database thread.start()
def copy_items(): if wxcopypaste_api and _select_database(): if _select_items(True): log.debug('Simulate copy items') # Databases are blocked in simulator._do_action core_api.release_databases() wxcopypaste_api.simulate_copy_items() else: # Databases are blocked in simulator._do_action core_api.release_databases() return False else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def edit_item(): if _select_database(): if _select_items(False): log.debug('Simulate edit item') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_edit_item() else: # Databases are blocked in simulator._do_action core_api.release_databases() return False else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def delete_items(): if _select_database(): if _select_items(True): log.debug('Simulate delete items') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_delete_items(no_confirm=True) else: # Databases are blocked in simulator._do_action core_api.release_databases() return False else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def start(): log.debug('Start simulator') DELAY = coreaux_api.get_plugin_configuration('wxdevelopment' ).get_int('simulator_delay') # Don't use a combination of threading.Timer and wx.CallAfter, both for # simplicity and because Timer.is_alive() doesn't seem to return False # immediately as the action is executed, and this way *sometimes* the # application would execute the stop function, which should be put at the # top of the restart fucntion, before actually restarting the timer (this # would be a minor bug anyway, but using wx.CallLater avoids it, so prefer # using it) global timer timer = wx.CallLater(DELAY, _do_action)
def save_database(): if _select_database(): if random.randint(0, 9) < 9: log.debug('Simulate save database') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_save_database() else: log.debug('Simulate save all databases') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_save_all_databases() else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def apply_editor(): if _select_editor(): if random.randint(0, 9) < 9: log.debug('Simulate apply editor') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_apply_editor() else: log.debug('Simulate apply all editors') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_apply_all_editors() else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def create_item(): if _select_database(): _select_items(False) if random.randint(0, 1) == 0: log.debug('Simulate create sibling item') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_create_sibling() else: log.debug('Simulate create child item') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_create_child() else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def paste_items(): if wxcopypaste_api and _select_database(): _select_items(False) if random.randint(0, 1) == 0: log.debug('Simulate paste items as siblings') # Databases are blocked in simulator._do_action core_api.release_databases() wxcopypaste_api.simulate_paste_items_as_siblings(no_confirm=True) else: log.debug('Simulate paste items as children') # Databases are blocked in simulator._do_action core_api.release_databases() wxcopypaste_api.simulate_paste_items_as_children(no_confirm=True) else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def link_item_to_selection(): if links_api and wxlinks_api and _select_editor(): filename, id_ = wxgui_api.get_selected_editor_identification() _select_items(False) if filename in links_api.get_supported_open_databases(): log.debug('Simulate link item to selection') # Databases are blocked in simulator._do_action core_api.release_databases() wxlinks_api.simulate_link_to_selection(filename, id_) else: # Databases are blocked in simulator._do_action core_api.release_databases() return False else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def edit_editor_text(): if _select_editor(): text = '' words = ('the quick brown fox jumps over the lazy dog ' * 6).split() seps = ' ' * 6 + '\n' for x in xrange(random.randint(10, 100)): words.append(str(random.randint(0, 100))) text = ''.join((text, random.choice(words), random.choice(seps))) text = ''.join((text, random.choice(words))).capitalize() log.debug('Simulate replace editor text') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_replace_editor_text(text) else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def open_database(): testfilesd = coreaux_api.get_plugin_configuration('wxdevelopment')( 'TestFiles') testfiles = [os.path.expanduser(testfilesd[key]) for key in testfilesd] random.shuffle(testfiles) while testfiles: filename = testfiles.pop() if not core_api.is_database_open(filename) and \ os.path.isfile(filename): log.debug('Simulate open database') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_open_database(filename) break else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def move_item(): if _select_database(): if _select_items(False): c = random.randint(0, 2) if c == 0: log.debug('Simulate move item up') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_move_item_up() elif c == 1: log.debug('Simulate move item down') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_move_item_down() else: log.debug('Simulate move item to parent') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_move_item_to_parent() else: # Databases are blocked in simulator._do_action core_api.release_databases() return False else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def _search_threaded_continue(self, regexp, filename, iterator, results, search_start): try: row = iterator.next() except StopIteration: log.debug('Search in {} completed in {} (time) / {} (clock) s' ''.format(filename, time.time() - search_start[0], time.clock() - search_start[1])) fname = os.path.basename(filename) # The gui must be updated in the main thread, so do it only once # when the search is *finished* instead of calling CallAfter every # time a match is found wx.CallAfter(self.results.display, filename, fname, results) else: id_ = row['I_id'] text = row['I_text'] heading = text.partition('\n')[0] try: if self.filters.option2.GetValue(): text = heading except wx.PyDeadObjectError: # If the application is closed while the search is ongoing, # this is where it would crash # If there were more problems, consider running this thread as # a daemon pass else: results = self._find_match_lines(regexp, id_, heading, text, results) # Use a recursion instead of a simple for loop, so that it will # be easy to stop the search from the main thread if needed self.search_threaded_action(regexp, filename, iterator, results, search_start)
def start(self): search_start = (time_.time(), time_.clock()) try: # Don't use Main.databases because the searched filenames must be # coherent with the other operations that this class is used in # Note that Main.databases could also change size during the # search, so it should be copied to iterate in it for filename in self.filenames: # Don'd iterate directly over the returned cursor, but use a # fetchall, otherwise if the application is closed while the # search is on (e.g. while searching the old alarms) an # exception will be raised, because the database will be closed # while the loop is still reading it rows = self.databases[filename].get_all_valid_item_rules( ).fetchall() for row in rows: id_ = row['R_id'] rules = Database.string_to_rules(row['R_rules']) for rule in rules: self._search_item(filename, id_, rule) # Get active alarms *after* all occurrences, to avoid except # rules get_alarms_event.signal(mint=self.mint, maxt=self.maxt, filename=filename, occs=self.occs) # All loops must be broken except OccurrencesRangeSearchStop: pass log.debug('Occurrences range found in {} (time) / {} (clock) s'.format( time_.time() - search_start[0], time_.clock() - search_start[1]))
def start(self): # Note that this function must be kept separate from # NextOccurrencesEngine because it can be used without the latter (e.g. # by wxtasklist); note also that both functions generate their own # events self.occs = NextOccurrences() self.utcoffset = timeaux.UTCOffset() search_start = (time_.time(), time_.clock()) try: for filename in self.filenames: if not self.base_time: self.base_time = self.base_times[filename] # Don't even think of moving this to the constructor, as # self.base_time could be defined just above utcbase = self.base_time - self.utcoffset.compute( self.base_time) for row in organism_api.get_all_valid_item_rules(filename): id_ = row['R_id'] rules = organism_api.convert_string_to_rules( row['R_rules']) for rule in rules: self._search_item(filename, id_, rule, utcbase) get_next_occurrences_event.signal(base_time=self.base_time, filename=filename, occs=self.occs) # All loops must be broken except NextOccurrencesSearchStop: pass log.debug('Next occurrences found in {} (time) / {} (clock) s'.format( time_.time() - search_start[0], time_.clock() - search_start[1]))
def close_editor(): if _select_editor(): apply_ = random.randint(0, 5) if random.randint(0, 9) < 9: log.debug('Simulate' + (' apply and ' if apply_ > 0 else ' ') + 'close editor') # Databases are blocked in simulator._do_action core_api.release_databases() if apply_ > 0: wxgui_api.simulate_apply_editor() wxgui_api.simulate_close_editor(ask='quiet') else: log.debug('Simulate' + (' apply and ' if apply_ > 0 else ' ') + 'close all editors') # Databases are blocked in simulator._do_action core_api.release_databases() if apply_ > 0: wxgui_api.simulate_apply_all_editors() wxgui_api.simulate_close_all_editors(ask='quiet') else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def close_database(): if _select_database(): save = random.randint(0, 5) if random.randint(0, 9) < 9: log.debug('Simulate' + (' save and ' if save > 0 else ' ') + 'close database') # Databases are blocked in simulator._do_action core_api.release_databases() if save > 0: wxgui_api.simulate_save_database() wxgui_api.simulate_close_database(no_confirm=True) else: log.debug('Simulate' + (' save and ' if save > 0 else ' ') + 'close all databases') # Databases are blocked in simulator._do_action core_api.release_databases() if save > 0: wxgui_api.simulate_save_all_databases() wxgui_api.simulate_close_all_databases(no_confirm=True) else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def dismiss_alarms(): if wxalarms_api: alarms = wxalarms_api.get_active_alarms() if alarms: if random.randint(0, 11) > 0: alarm = random.choice(alarms) log.debug('Simulate dismiss alarm') # Databases are blocked in simulator._do_action core_api.release_databases() wxalarms_api.simulate_dismiss_alarm(alarm['filename'], alarm['alarmid']) else: log.debug('Simulate dismiss all alarms') # Databases are blocked in simulator._do_action core_api.release_databases() wxalarms_api.simulate_dismiss_all_alarms() else: # Databases are blocked in simulator._do_action core_api.release_databases() return False else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def snooze_alarms(): if wxalarms_api: alarms = wxalarms_api.get_active_alarms() if alarms: unit = random.choice(('minutes', 'hours', 'days', 'weeks')) if unit == 'minutes': number = random.randint(1, 360) elif unit == 'hours': number = random.randint(1, 24) elif unit == 'days': number = random.randint(1, 3) elif unit == 'weeks': number = random.randint(1, 2) wxalarms_api.simulate_set_snooze_time(number, unit) if random.randint(0, 11) > 0: alarm = random.choice(alarms) log.debug('Simulate snooze alarm') # Databases are blocked in simulator._do_action core_api.release_databases() wxalarms_api.simulate_snooze_alarm(alarm['filename'], alarm['alarmid']) else: log.debug('Simulate snooze all alarms') # Databases are blocked in simulator._do_action core_api.release_databases() wxalarms_api.simulate_snooze_all_alarms() else: # Databases are blocked in simulator._do_action core_api.release_databases() return False else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def create_database(): testfilesd = coreaux_api.get_plugin_configuration('wxdevelopment')( 'TestFiles') testfiles = [os.path.expanduser(testfilesd[key]) for key in testfilesd] random.shuffle(testfiles) while testfiles: filename = testfiles.pop() if not core_api.is_database_open(filename): try: os.remove(filename) except OSError: # filename doesn't exist yet pass log.debug('Simulate create database') # Databases are blocked in simulator._do_action core_api.release_databases() wxgui_api.simulate_create_database(filename) break else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def edit_editor_rules(): if organism_api and wxscheduler_api and wxscheduler_basicrules_api and \ _select_editor(): filename, id_ = wxgui_api.get_selected_editor_identification() # It should also be checked if the database supports # organism_basicrules (bug #330) if filename in organism_api.get_supported_open_databases(): wxscheduler_api.simulate_expand_rules_panel(filename, id_) wxscheduler_api.simulate_remove_all_rules(filename, id_) rules = [] for n in xrange(random.randint(0, 8)): r = random.randint(0, 16) if r == 0: rule = \ wxscheduler_basicrules_api.create_random_occur_once_rule() elif r == 1: rule = \ wxscheduler_basicrules_api.create_random_occur_every_interval_rule() elif r == 2: rule = \ wxscheduler_basicrules_api.create_random_occur_every_day_rule() elif r == 3: rule = \ wxscheduler_basicrules_api.create_random_occur_every_week_rule() elif r == 4: rule = \ wxscheduler_basicrules_api.create_random_occur_selected_weekdays_rule() elif r == 5: rule = \ wxscheduler_basicrules_api.create_random_occur_selected_months_rule() elif r == 6: rule = \ wxscheduler_basicrules_api.create_random_occur_selected_months_inverse_rule() elif r == 7: rule = \ wxscheduler_basicrules_api.create_random_occur_selected_months_weekday_rule() elif r == 8: rule = \ wxscheduler_basicrules_api.create_random_occur_selected_months_weekday_inverse_rule() elif r == 9: rule = \ wxscheduler_basicrules_api.create_random_occur_every_month_rule() elif r == 10: rule = \ wxscheduler_basicrules_api.create_random_occur_every_month_inverse_rule() elif r == 11: rule = \ wxscheduler_basicrules_api.create_random_occur_every_month_weekday_rule() elif r == 12: rule = \ wxscheduler_basicrules_api.create_random_occur_every_month_weekday_inverse_rule() elif r == 13: rule = \ wxscheduler_basicrules_api.create_random_occur_every_synodic_month_rule() elif r == 14: rule = \ wxscheduler_basicrules_api.create_random_occur_yearly_rule() elif r == 15: rule = \ wxscheduler_basicrules_api.create_random_except_once_rule() else: rule = \ wxscheduler_basicrules_api.create_random_except_every_interval_rule() rules.append(rule) log.debug('Simulate replace item rules') # Databases are blocked in simulator._do_action core_api.release_databases() for rule in rules: if rule['rule'] in ('occur_once_local', 'occur_once_UTC'): wxscheduler_basicrules_api.simulate_create_occur_once_rule( filename, id_, rule) elif rule['rule'] in ('occur_regularly_local', 'occur_regularly_UTC'): if rule['#'][6][0] == '1d': wxscheduler_basicrules_api.simulate_create_occur_every_day_rule( filename, id_, rule) elif rule['#'][6][0] == '1w': wxscheduler_basicrules_api.simulate_create_occur_every_week_rule( filename, id_, rule) elif rule['#'][6][0] == 'sy': wxscheduler_basicrules_api.simulate_create_occur_every_synodic_month_rule( filename, id_, rule) else: wxscheduler_basicrules_api.simulate_create_occur_every_interval_rule( filename, id_, rule) elif rule['rule'] in ('occur_regularly_group_local', 'occur_regularly_group_UTC'): if rule['#'][6][0] == 'sw': wxscheduler_basicrules_api.simulate_create_occur_selected_weekdays_rule( filename, id_, rule) elif rule['rule'] in ('occur_monthly_number_direct_local', 'occur_monthly_number_direct_UTC'): if rule['#'][7][0] == '1m': wxscheduler_basicrules_api.simulate_create_occur_every_month_rule( filename, id_, rule) else: wxscheduler_basicrules_api.simulate_create_occur_selected_months_rule( filename, id_, rule) elif rule['rule'] in ('occur_monthly_number_inverse_local', 'occur_monthly_number_inverse_UTC'): if rule['#'][7][0] == '1m': wxscheduler_basicrules_api.simulate_create_occur_every_month_inverse_rule( filename, id_, rule) else: wxscheduler_basicrules_api.simulate_create_occur_selected_months_inverse_rule( filename, id_, rule) elif rule['rule'] in ('occur_monthly_weekday_direct_local', 'occur_monthly_weekday_direct_UTC'): if rule['#'][8][0] == '1m': wxscheduler_basicrules_api.simulate_create_occur_every_month_weekday_rule( filename, id_, rule) else: wxscheduler_basicrules_api.simulate_create_occur_selected_months_weekday_rule( filename, id_, rule) elif rule['rule'] in ('occur_monthly_weekday_inverse_local', 'occur_monthly_weekday_inverse_UTC'): if rule['#'][8][0] == '1m': wxscheduler_basicrules_api.simulate_create_occur_every_month_weekday_inverse_rule( filename, id_, rule) else: wxscheduler_basicrules_api.simulate_create_occur_selected_months_weekday_inverse_rule( filename, id_, rule) elif rule['rule'] in ('occur_yearly_local', 'occur_yearly_UTC'): wxscheduler_basicrules_api.simulate_create_occur_yearly_rule( filename, id_, rule) elif rule['rule'] in ('except_once_local', 'except_once_UTC'): wxscheduler_basicrules_api.simulate_create_except_once_rule( filename, id_, rule) elif rule['rule'] in ('except_regularly_local', 'except_regularly_UTC'): wxscheduler_basicrules_api.simulate_create_except_every_interval_rule( filename, id_, rule) else: # Databases are blocked in simulator._do_action core_api.release_databases() return False else: # Databases are blocked in simulator._do_action core_api.release_databases() return False
def cancel(self): if self.timer.is_alive(): log.debug('Cancel timer') self.timer.cancel()
def release(self): log.debug("Release databases") self.q.task_done() self.q.join() self.q.put(self.s)