def Do_Shock_Run(self): try: self.experiment.get("ShockerCalibration") except: oslogger.error("No calibration step taken: First run a Shocker in calibration mode!") return if (self.var._productName == u"DUMMY"): oslogger.info("In (Dummy) Shock: shocking with value: " + str(self.var._value)) else: try: lst = self.experiment.get("lastShockTime") except: lst = 0; td = time.time() - lst # This line is to prevent the possibility to shock if the previous shock was less then the minimum time ago if (td > self.var._min_intershock_interval): oslogger.info("In (Hardware) Shock: shocking with value: " + str(math.floor((self.var._value/100.0) * self.experiment.get("ShockerCalibration")))) self.EE.SetLines(0) self.EE.PulseLines(math.floor((self.var._value/100.0) * self.experiment.get("ShockerCalibration")), self.var._duration) # TODO: mAh = round((self.var._value/100.0) * self.experiment.get("ShockermAhCalibration"),2) self.experiment.set("lastShockTime", time.time()) self.experiment.set("BinaryShockValue", math.floor((self.var._value/100.0) * self.experiment.get("ShockerCalibration"))) self.experiment.set("ShockPercValue", self.var._value) self.experiment.set("ShockMahValue", mAh) else: oslogger.warning("In Shock: the shock came too early: please don't give shocks in rapid succession!")
def _set_language(self, language, editor=None): if language is None: return # Getting the current editor if none was given if editor is None: if 'OpenSesameIDE' not in self.extension_manager: oslogger.warning('SpellCheck requires OpenSesameIDE') return editor = self.extension_manager['OpenSesameIDE']._current_editor() if editor is None: return if 'SpellCheckerMode' in editor.modes.keys(): editor.modes.remove('SpellCheckerMode') try: import spellchecker except ImportError: oslogger.warning('failed to import spellchecker') self.extension_manager.fire( 'notify', message=_('Please install pyspellchecker for spell checking')) return oslogger.debug('enabling spellcheck for {}'.format(editor)) spellchecker = modes.SpellCheckerMode() spellchecker.set_ignore_rules(language) editor.modes.append(spellchecker)
def event_startup(self): # Loop through all code edit classes that are bundles with the # extension and register them if they're enabled in the configuration. for key in dir(lsp_code_edit_widgets): cls = getattr(lsp_code_edit_widgets, key) # Check if it's a code edit class if not isinstance(cls, type) or not issubclass(cls, CodeEdit): continue # Check if the language server is configured and enabled try: enabled = cfg['lsp_enable_{}'.format(cls.language.lower())] except BaseException: oslogger.warning( '{} language server is missing in config'.format( cls.language)) continue if not enabled: oslogger.debug( '{} language server is disabled in config'.format( cls.language)) continue oslogger.debug('{} language server enabled'.format(cls.language)) cls.extension_manager = self.extension_manager SplittableCodeEditTabWidget.register_code_edit(cls)
def _update(self, name, workspace_func): if (not hasattr(self, '_dock_widget') or not self._dock_widget.isVisible()): return self._dock_widget.setWindowTitle(_(u'Workspace ({})').format(name)) workspace = workspace_func() # If the workspace didn't reply, we try again in a second if workspace is None or workspace.get(u'no reply', False) is None: QTimer.singleShot(1000, lambda: self._update(name, workspace_func)) return # If the current kernel doesn't expose its workspace, indicate this if workspace.get(u'not supported', False) is None: dm = DataMatrix(length=0) dm.kernel_not_supported = -1 # Create a DataMatrix that exposes the workspace else: dm = DataMatrix(length=len(workspace)) dm.sorted = False dm.name = '' dm.value = '' dm.shape = '' dm.type = '' for row, (var, data) in zip(dm, workspace.items()): if data is None: oslogger.warning(u'invalid workspace data: {}'.format(var)) continue value, type_, shape = data row.value = value row.name = var if shape is not None: row.shape = repr(shape) row.type = type_ self._qdm.dm = dm self._qdm.refresh()
def run_debug(self, path, breakpoints): # This should be changed into a kernel-agnostic implementation if ( self._kernel not in ('python', 'python2', 'python3') or self._inprocess ): self.extension_manager.fire( 'notify', message=_(u'The {} (inprocess={}) kernel does not support debugging').format( self._kernel, self._inprocess ) ) return code = self.extension_manager.provide( 'python_debugger_code', path=path, breakpoints=breakpoints ) if not code: oslogger.warning('no Python debugger code received') return silent_code, nonsilent_code = code # RapunzelPDB and debugfile() are silently loaded into the workspace, # and then the debugger is callend in a nonsilent way.` self._jupyter_widget._kernel_client.execute(silent_code, silent=True) self.execute(nonsilent_code)
def activate(self): self.main_window.set_busy(True) editor = self.extension_manager.provide(u'ide_current_editor') haystack = [] if editor is not None and 'SymbolsMode' in editor.modes.keys(): lsp_symbols = editor.modes.get('SymbolsMode').request_symbols() for name, kind, lineno, container in lsp_symbols: if container is not None: name = '{}.{}'.format(container, name) haystack.append((name, lineno + 1, self._jump_to_line)) else: mimetype = self.extension_manager.provide(u'ide_current_language') try: fnc = getattr(self, u'_get_{}_symbols'.format(mimetype)) except AttributeError: oslogger.warning( u'don\'t know how to handle {}'.format(mimetype)) self.main_window.set_busy(False) return symbols = fnc( self.extension_manager.provide(u'ide_current_source')) for name, lineno in symbols: haystack.append((name, lineno, self._jump_to_line)) self.main_window.set_busy(False) self.extension_manager.fire( u'quick_select', haystack=haystack, placeholder_text=_(u'Search symbols in current file …'))
def run(self): # We dynamically set the custom log backend module so that it's # automatically found by OpenSesame. from openmonkeymind import _omm_log_backend sys.modules['openexp._log.omm'] = _omm_log_backend # Get the experiment and patch it so that re-uses the environment of # the current experiment, i.e. it doesn't create its own window etc. try: # Strip the / characters from the participant id exp = self._openmonkeymind.announce(self.var.omm_participant[1:-1]) except (ParticipantNotFound, NoJobsForParticipant, requests.exceptions.ConnectionError) as e: oslogger.warning(e) exp = self._fallback_experiment() item_stack.item_stack_singleton.clear = lambda: None exp.init_display = lambda: None exp.end = lambda: exp.cleanup() # only call cleanup functions exp.window = self.experiment.window exp.var.width = self.experiment.var.width exp.var.height = self.experiment.var.height exp.logfile = self.var.omm_local_logfile exp.python_workspace['win'] = self.experiment.window exp.python_workspace['omm'] = self._openmonkeymind # A few back-end-specific properties need to be copied to the # experiment. if self.experiment.var.canvas_backend == 'xpyriment': exp.expyriment = self.experiment.expyriment elif self.experiment.var.canvas_backend == 'legacy': exp.surface = self.experiment.surface # The backend settings need to be copied as well, although the log # backend is always set to omm. exp.var.log_backend = 'omm' for backend in [ 'canvas_backend', 'keyboard_backend', 'mouse_backend', 'sampler_backend', 'clock_backend', 'color_backend' ]: if backend in exp.var: if backend in self.experiment.var: exp.var.set(backend, self.experiment.var.get(backend)) else: exp.var.__delattr__(backend) # The YAML data specified in the extension or the OMMAnnounce item try: yaml_data = yaml.safe_load(self.var.omm_yaml_data) if yaml_data is None: yaml_data = {} assert (isinstance(yaml_data, dict)) except: raise ValueError('YAML data is not a valid YAML dict') for key, value in yaml_data.items(): exp.var.set(key, value) # The metadata associated with the participant for key, value in self._openmonkeymind.participant_metadata.items(): exp.var.set(key, value) exp.run()
def _register_mimetypes(self): try: custom_mimetypes = safe_yaml_load(cfg.opensesame_ide_mimetypes) assert (isinstance(custom_mimetypes, dict)) except Exception: oslogger.warning('failed to parse mimetypes') return for ext, mimetype in custom_mimetypes.items(): mimetypes.add_type(mimetype, ext)
def _inspect_fallback(self, value): if hasattr(value, '_repr_html_') and callable(value._repr_html_): return inspect_str(value._repr_html_()) try: value = pprint.pformat(value) except Exception as e: oslogger.warning('failed to pretty-print: {!s}'.format(e)) value = repr(value) return inspect_str(value)
def _can_serialize(self, var, val): try: json.dumps(val) except TypeError: oslogger.warning( 'failed to send variable {} to server'.format(var) ) return False return True
def _refresh_ignore(self): if 'pyqode_manager' not in self.extension_manager: oslogger.warning('SpellCheck requires pyqode_manager') return for editor in self.extension_manager['pyqode_manager']._editors: if 'SpellCheckerMode' not in editor.modes.keys(): continue spellchecker_mode = editor.modes.get('SpellCheckerMode') spellchecker_mode.add_extra_info('ignore', self._ignore_list()) spellchecker_mode.request_analysis()
def pid(self): if self.language: return os.getpid() if self._kernel not in PID_CMD: return -1 for i in range(10): pid = self._jupyter_widget._silent_execute(PID_CMD[self._kernel]) if isinstance(pid, int): return pid time.sleep(0.1) oslogger.warning('failed to get pid') return -1
def _notebook_img_cell(type_, img_path, execution_count): base, ext = os.path.splitext(img_path.lower()) if ext == '.png': fmt = 'image/png' elif ext in ('.jpg', '.jpeg'): fmt = 'image/jpeg' elif ext == '.svg': fmt = 'image/svg+xml' else: oslogger.warning('unknown image format: {}'.format(img_path)) return {} with open(img_path, 'rb') as fd: data = base64.b64encode(fd.read()) return _notebook_output_cell(fmt, data, execution_count)
def _set_language(self, language, editor=None): # Getting the current editor if none was given if editor is None: if 'OpenSesameIDE' not in self.extension_manager: oslogger.warning('SpellCheck requires OpenSesameIDE') return editor = self.extension_manager['OpenSesameIDE']._current_editor() if editor is None: return if 'SpellCheckerMode' in editor.modes.keys(): editor.modes.remove('SpellCheckerMode') if hasattr(editor, 'action_ignore_word'): editor.action_ignore_word.triggered.disconnect( self._ignore_current) editor.remove_action(editor.action_ignore_word, sub_menu=_('Spell checking')) editor.action_clear_ignore.triggered.disconnect( self._clear_ignore) editor.remove_action(editor.action_clear_ignore, sub_menu=_('Spell checking')) if language is None: return # disable spell checker try: import spellchecker except ImportError: oslogger.warning('failed to import spellchecker') self.extension_manager.fire( 'notify', message=_('Please install pyspellchecker for spell checking')) return oslogger.debug('enabling spellcheck for {}'.format(editor)) spellchecker = modes.SpellCheckerMode() spellchecker.add_extra_info('language', language) spellchecker.add_extra_info('ignore', self._ignore_list()) editor.modes.append(spellchecker) # Add context menu actions editor.action_ignore_word = QAction(_('Add word to custom dictionary'), editor) editor.action_ignore_word.triggered.connect(self._ignore_current) editor.add_action(editor.action_ignore_word, sub_menu=_('Spell checking')) editor.action_clear_ignore = QAction(_('Clear custom dictionary'), editor) editor.action_clear_ignore.triggered.connect(self._clear_ignore) editor.add_action(editor.action_clear_ignore, sub_menu=_('Spell checking'))
def activate(self): mimetype = self.extension_manager.provide(u'ide_current_language') try: fnc = getattr(self, u'_get_{}_symbols'.format(mimetype)) except AttributeError: oslogger.warning(u'don\'t know how to handle {}'.format(mimetype)) return symbols = fnc(self.extension_manager.provide(u'ide_current_source')) haystack = [] for name, lineno in symbols: haystack.append((name, lineno, self._jump_to_line)) self.extension_manager.fire( u'quick_select', haystack=haystack, placeholder_text=_(u'Search symbols in current file …') )
def _set_language(self, language, editor=None): if language is None: return # Getting the current editor if none was given if editor is None: if 'OpenSesameIDE' not in self.extension_manager: oslogger.warning('SpellCheck requires OpenSesameIDE') return editor = self.extension_manager['OpenSesameIDE']._current_editor() if editor is None: return if 'SpellCheckerMode' in editor.modes.keys(): editor.modes.remove('SpellCheckerMode') oslogger.debug('enabling spellcheck for {}'.format(editor)) spellchecker = modes.SpellCheckerMode() spellchecker.set_ignore_rules(language) editor.modes.append(spellchecker)
def prepare(self): self.experiment.set("ShockDuration", self.var._duration) self.var._min_intershock_interval = 1 item.item.prepare(self) self.EE = EvtExchanger() Device = self.EE.Select(self.var._productName) try: if Device is None: raise except: self.var._productName = u"DUMMY" oslogger.warning("Did not find a shocker: code to debugwindow") if self.var._calibrate == u"Calibrate": self.Calibrate_Prepare() elif self.var._calibrate == u"Shock": self.Do_Shock_Prepare()
def _run_rfid(self): import serial keyboard = Keyboard(self.experiment, timeout=0) s = serial.Serial(self.var.serial_port, timeout=0.01) s.flushInput() buffer = b'' while True: # Also accept key presses as RFIDs for testing. key, _ = keyboard.get_key() if key: rfid = key break # Read at most RFID_LENGTH bytes from the serial port. This can # also result in fewer bytes. buffer += s.read(RFID_LENGTH) # Split the buffer based on the RFID separator byte, and keep only # those elements that have the expected length, in case the buffer # contains some fragments of RFIDs. rfids = [ rfid for rfid in buffer.split(RFID_SEP) if len(rfid) == RFID_LENGTH ] # If there more than one different RFIDs, then something went wrong # and we reset the buffer. if len(set(rfids)) > 1: oslogger.warning('inconsistent rfids') buffer = b'' continue # If we have the minimum of repetitions of the RFID, then we are # satisfied and return the first RFID. if len(rfids) >= MIN_REP: rfid = safe_decode(rfids[0]) break oslogger.warning('rfid detected: {}'.format(rfid)) s.close() self.experiment.var.set( self.var.participant_variable, '/{}/'.format(rfid) # Flank with / to make sure it's a string )
def parachute(queue, main_pid): """This function runs as a subprocess and receives the PIDs off all subprocesses. Whether the main process is alive is kept track of with a heartbeat. If no heartbeat comes in, then all subprocesses are killed to make sure that no runaway processes are left on shutdown. """ oslogger.start('parachute') pids = [main_pid] oslogger.debug('main-process PID: {}'.format(main_pid)) while True: try: pid = queue.get(True, 2 * PARACHUTE_HEARTBEAT_INTERVAL) except (Empty, ValueError, OSError): # If something is blocking the main process, the heartbeat stops. # This can happen for example if something is executed in an # in-process console. In that case we don't want to kill everything # off. if psutil.pid_exists(main_pid): oslogger.warning('main process is alive but unresponsive') continue oslogger.warning('main process appears to have died') break if pid == PARACHUTE_STOP: oslogger.debug('parchute stop') return if pid == PARACHUTE_HEARTBEAT: continue oslogger.debug('subprocess PID: {}'.format(pid)) pids.append(pid) for pid in filter(psutil.pid_exists, pids): oslogger.warning('parachute killing PID: {}'.format(pid)) p = psutil.Process(pid) p.kill()
def event_ide_search_text(self, needle): """ desc: Conducts a case-insensitive search for a needle in the current editor. The search starts from the cursor position, or from the start if no match was found after the cursor position. arguments: needle: desc: The search needle. type: str """ editor = self._current_editor() if editor is None: return u'' try: search_panel = editor.panels.get('SearchAndReplacePanel') except KeyError: return # Panel is not installed cursor = editor.textCursor() needle = needle.lower() code = editor.toPlainText().lower() # First search from current cursor position needle_pos = code.find(needle, cursor.position()) # If the needle is not found, search from the start of the code if needle_pos < 0: needle_pos = code.find(needle) # If the needle still not found, then it doesn't exist. if needle_pos < 0: oslogger.warning('failed to find needle in text') return cursor.clearSelection() cursor.movePosition(cursor.Start, cursor.MoveAnchor) cursor.movePosition(cursor.NextCharacter, cursor.MoveAnchor, needle_pos) cursor.movePosition(cursor.NextCharacter, cursor.KeepAnchor, len(needle)) editor.setTextCursor(cursor) search_panel.on_search()
def event_jupyter_execute_result_image(self, img, fmt, code): """Receives a new image annotation, where `img` is the image data, `fmt` is the format, and code is the code snippet that resulted in creating of the image. """ if code is None: oslogger.warning('received None code') return try: mode = self._editor.modes.get('ImageAnnotationsMode') except (AttributeError, KeyError): return if self._editor.file.path not in self._image_annotations: self._image_annotations[self._editor.file.path] = {} if code not in self._image_annotations[self._editor.file.path]: self._image_annotations[self._editor.file.path][code] = [] img_path = self._img_to_file(img, fmt) self._image_annotations[self._editor.file.path][code].append(img_path) if cfg.image_annotations_capture_output: md = '![]({})'.format(img_path) self._image_annotations[self._editor.file.path][md] = [img_path] self.event_jupyter_execute_result_text(md) self._set_annotations(self._editor, mode)
def event_startup(self): """Creates a folder for the image files if it doesn't exist, and restores the image annotation info. """ self._capturing = False self._hourglass = 0 self._editor = None self.enable_capture = False self._image_folder = os.path.join(self.main_window.home_folder, '.opensesame', 'image_annotations') if not os.path.exists(self._image_folder): oslogger.debug('creating {}'.format(self._image_folder)) os.mkdir(self._image_folder) try: self._image_annotations = safe_yaml_load(cfg.image_annotations) assert (isinstance(self._image_annotations, dict)) except BaseException: oslogger.warning('failed to parse image annotations from config') self._image_annotations = {} # Remove annotations for non-existing images and convert single # annotations to lists of annotations so that there can be multiple # annotations for the same code. The `list()` wrapping is necessary # so that we can modify the objects while iterating through them. for file_path, file_annotations in list( self._image_annotations.items()): if not isinstance(file_annotations, dict): self._image_annotations[file_path] = {} continue for code, paths in list(file_annotations.items()): if isinstance(paths, basestring): paths = [paths] paths = [path for path in paths if os.path.exists(path)] if paths: file_annotations[code] = paths else: del file_annotations[code]
def run(self): oslogger.warning( 'inline_html items require OSWeb and do nothing on the desktop' )