class RedisManager(object): def __init__(self, config=None): self.config = config self.__r = None self.__t = Timer(2, self.__conn) def __conn(self): try: self._conn().get('__test') if self.__t.is_alive(): self.__t.cancel() except Exception as e: pp("redis 链接失败:{}".format(e), red, print) def conn(self): try: _r = self._conn() _r.get('__test') return _r except Exception as e: print(e) if not self.__t.is_alive(): self.__t.start() def _conn(self): _r = self.config host = _r.get("host") port = _r.get("port") password = _r.get("password") db = _r.get("db", 0) kwargs = _r.get("kwargs", {}) return redis.Redis(connection_pool=redis.ConnectionPool( host=host, port=port, db=db, password=password, **kwargs))
def exec_node(config, execute_with=None): """ Executes a node linked with a specific configuration file :param config: Path of the configuration file :param execute_with: To run under valgrind, or another program, specify the path to its executable and optionally some flags to it as a string list. :return: Returns the node process, the return code and a return message """ NODE_BUILD_PATH = "src/node/tchsm_node" NODE_PATH = join(EXEC_PATH, NODE_BUILD_PATH) if not isdir(EXEC_PATH): return None, 1, "ERROR: Path doesn't exists >> " + EXEC_PATH if not isdir(dirname(NODE_PATH)): return None, 1, "ERROR: Path doesn't exists >> " + dirname(NODE_PATH) node = None try: if DEBUG: print(" DEBUG::NODE_CALL: %s" % ' '.join([NODE_PATH, '-c', config + ".conf"])) args = [NODE_PATH, "-c", config + ".conf"] if execute_with is not None: args = execute_with + args node = subprocess.Popen(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE) except OSError: return node, 1, "ERROR: Exec could not be accessed >> " + EXEC_PATH + NODE_BUILD_PATH if node.returncode is not None: return node, node.returncode, "ERROR: Node finished with return code >> " + str(node.returncode) timer = Timer(NODE_TIMEOUT * 3, terminate_subprocess, [node]) timer.start() node_stderr = node.stderr stderr_lines = iter(node_stderr.readline, "") for stderr_line in stderr_lines: stderr_line_decoded = stderr_line.decode() if DEBUG: if not (stderr_line_decoded.isspace() or (len(stderr_line) == 0)): sys.stdout.write( " DEBUG::STDERR --> " + stderr_line_decoded) if NODE_RDY in stderr_line_decoded: break if not timer.is_alive(): timer.cancel() return node, 1, "FAILURE: Node timeout" if timer.is_alive(): timer.cancel() return node, 0, "" else: return node, -1, "FAILURE: Node didn't exit on time"
class StoreDevice(GenericDevice): """ Store """ def __init__(self, channels, name): GenericDevice.__init__(self, channels, name) self.name = name self.type_ = 'Store' self.exoup = channels['up']['exo'] self.channelup = channels['up']['channel'] self.exodown = channels['down']['exo'] self.channeldown = channels['down']['channel'] self.tmr = Timer( 1, self.exoup.set_output, [self.channelup, 0]) self.openratio = None def set_value(self, cmd): """ Set device status """ if ( cmd == 'up' and self.exoup.get_output(self.channelup) == 0): if self.tmr.is_alive(): self.tmr.cancel() if self.exodown.get_output(self.channeldown) != 0 : self.exodown.set_output(self.channeldown, 0) time.sleep(0.3) self.exoup.set_output(self.channelup, 255) self.tmr = Timer(30, self.exoup.set_output, [self.channelup, 0]) self.tmr.start() if ( cmd == 'down' and self.exodown.get_output(self.channeldown) == 0): if self.tmr.is_alive(): self.tmr.cancel() if ( self.exoup.get_output(self.channelup) != 0 ): self.exoup.set_output(self.channelup, 0) time.sleep(0.3) self.exodown.set_output(self.channeldown, 255) self.tmr = Timer(30, self.exodown.set_output, [self.channeldown, 0]) self.tmr.start() if ( cmd == 'stop' ): if ( self.tmr.is_alive() ): self.tmr.cancel() if ( self.exoup.get_output(self.channelup) !=0 ): self.exoup.set_output(self.channelup, 0) elif ( self.exodown.get_output(self.channeldown) != 0 ): self.exodown.set_output(self.channeldown, 0) def get_value(self): """ Get store status """ if ( self.exoup.get_output(self.channelup) != 0 ): return('up') elif ( self.exodown.get_output(self.channeldown) !=0 ): return('down') else: return('stop')
def pop_bumpers(): def boolTimer(timeUp): return not timeUp global score zeroCount = 0 lowHigh = True #Start by looking for a low to high transition (switch pressed) highLow = False #Use for after low to high transition detected timeUp = False alarm = Timer(0.1, boolTimer, timeUp) while (True): if ((GPIO.input(10) or GPIO.input(11) or GPIO.input(12) or GPIO.input(13) ) == GPIO.HIGH): #if ball touches any of the 4 pop bumpers #Nested ifs to track only the transitions we are looking for if (lowHigh): if ((GPIO.input(10) or GPIO.input(11) or GPIO.input(12) or GPIO.input(13)) == GPIO.HIGH): lowHigh = False highLow = True if not (alarm.is_alive()): alarm.cancel() alarm.start() else: alarm.start() if (highLow): if ((GPIO.input(10) or GPIO.input(11) or GPIO.input(12) or GPIO.input(13)) == GPIO.LOW): lowHigh = True highLow = False zeroCount = zeroCount + 1 #only count high to low transitions AFTER #a low to high transition has occured if not (alarm.is_alive()): alarm.cancel() alarm.start() else: alarm.start() if (zeroCount >= 3 ): #Only increase score after a certain number of zeros score = score + 100 zeroCount = 0 #Reset zeroCount lowHigh = True #Make sure Booleans are correctly reset highLow = False soundObj = pygame.mixer.Sound("bell-ding.wav") soundObj.play() if (timeUp): zeroCount = 0 #Reset zeroCount lowHigh = True #Make sure Booleans are correctly reset highLow = False timeUp = False #Reset Timer variable
class System(): def __init__(self, config): # create initial timer instance self.timeout = config.getint('System', 'DisplayOffTimeout', fallback=300) if self.timeout == -1: print('No display control') return self.timer = Timer(2 * self.timeout, self.backlightOFF) self.backlightOn = False def backlightON(self): if self.timeout == -1: return if self.timer.is_alive(): self.timer.cancel() if not self.backlightOn: print('Turn backlight ON') #f = open('/sys/class/backlight/rpi_backlight/bl_power', 'w') #f.write('0') #f.close() subprocess.call(["xset", "dpms", "force", "on"]) self.backlightOn = True def backlightOFF(self): if self.timeout == -1: return if self.timer.is_alive(): self.timer.cancel() print('Turn backlight OFF') #f = open('/sys/class/backlight/rpi_backlight/bl_power', 'w') #f.write('1') #f.close() #subprocess.call(["xset","dpms","force","off"]) subprocess.Popen("sleep 1; xset dpms force off", shell=True) self.backlightOn = False def backlightOffTimer(self): if self.timeout == -1: return if self.timeout == 0: self.backlightOFF() return if self.timer.is_alive(): self.timer.cancel() print('Set backlight OFF timer: ' + str(self.timeout) + " sec") self.timer = Timer(self.timeout, self.backlightOFF) self.timer.start() self.backlightOn = False
def wait_for(self, answer, error_message): answer_timer = Timer(10, self.answer_not_found, args=error_message) robot_answer = "" #if answer is not found after 10 seconds print error message while robot_answer != answer: robot_output = self.receive_str() if robot_output.find(answer) == -1 & answer_timer.is_alive() is False: answer_timer.start() answer_timer.join() elif robot_output.find(answer) != -1: robot_answer = answer
class StatusSaverService(AbstractUserService): """ Service which is responsible for scheduling dumping system into file periodically. """ autoload = True #: Dump saving interval, in seconds. Default 30 minutes. dump_interval = CFloat(30 * 60) _exit = CBool(False) _timer = Any(transient=True) def setup(self): if self.system.filename: self.system.on_trait_change(self.exit_save, "pre_exit_trigger") if self.dump_interval: self.save_system_periodically() def save_system_periodically(self): self.logger.debug('Saving system state') self.system.save_state() self._timer = Timer(self.dump_interval, self.save_system_periodically) self._timer.start() def exit_save(self): self.system.save_state() self._exit = True def cleanup(self): if self._timer and self._timer.is_alive(): self._timer.cancel()
class Countdown(object): def __init__ (self, session=None, name=None, start_time=0, total_time=0, sound=None): assert(total_time > 0) self.session = session self.name = name self.start_time = start_time or time.time() self.sound = sound or self.session.config['sounds']['countdownFinished'] self.total_time = total_time self.timer = Timer(total_time, self.countdown_complete) def start (self): self.timer.start() def cancel (self): if self.timer.is_alive: self.timer.cancel() stop = cancel def remaining_time (self): return int(self.timer.is_alive()) and self.total_time - (time.time() - self.start_time) def countdown_complete (self): self.session.countdowns.remove(self) output.speak(_("Countdown %s complete.") % self.name, True) self.play(self.sound)
class FetchTimer: def __init__(self): self.fetchTimer = None def startNow(self): self.start(0.1) def startLater(self): # Calculate how long before we fetch again now = datetime.datetime.now() runat = now.replace(hour=00, minute=00, second=01, microsecond=00) seconds = (runat - now).total_seconds() # seconds will be negative when the refresh time has already passed for today # In this case, just do it tomorrow by adding one day if seconds <= 0: seconds += 60 * 60 * 24 self.start(seconds) def start(self, seconds): m, s = divmod(seconds, 60) h, m = divmod(m, 60) logging.debug("Next schedule fetch in %d:%02d:%02d" % (h, m, s)) self.fetchTimer = Timer(seconds, setScheduleFromServer) self.fetchTimer.start() def stop(self): if not self.fetchTimer is None and self.fetchTimer.is_alive(): self.fetchTimer.cancel() self.fetchTimer.join()
def q2(): GPIO.setmode(GPIO.BCM) GPIO.setup(LED,GPIO.OUT) GPIO.setup(KEY, GPIO.IN, GPIO.PUD_UP) freq = 2 p = GPIO.PWM(LED, freq) t = None try: while True: GPIO.wait_for_edge(KEY, GPIO.RISING, bouncetime=100) if not t: freq = 2 p.ChangeFrequency(freq) p.start(10) t = Timer(0.3, multi, [p, freq]) t.start() elif t and t.is_alive(): t.cancel() t = None p.stop() else: freq *= 2 t = Timer(0.3, multi, [p, freq]) t.start() except KeyboardInterrupt: p.stop() GPIO.cleanup()
class BoxLock(I2CModule): OPEN_TIME = 6 def __init__(self, bus, addr=0x39): super().__init__(bus, addr) self._open = False self.write_byte(0xFF) self.scheduler = scheduler(time.time, time.sleep) self.timer = Timer(0, self.close) @property def powered(self): return bool(self.read_byte()[1] & 0x40) def open(self): if self._open: if not self.timer.is_alive(): logger.error('Lock open and timer not running! Closing.') self.close() else: s = self.write_byte(0x7F) if s: self._open = True self.timer = Timer(self.OPEN_TIME, self.close) self.timer.start() def close(self): s = self.write_byte(0xFF) if s: self._open = False else: logger.error('Solenoid close failed!!!!') self.timer = Timer(1, self.close) self.timer.start()
def start(self): if self.reporter != None: timer = Timer(1, self.reporter.start, kwargs={}) self.timer.append(timer) timer.start() for watcher in self.observers: if serviceconfig.isWin32() == True: timer = Timer(1, watcher.start, kwargs={}) else: timer = Timer(1, watcher.startScandir, kwargs={}) self.timer.append(timer) timer.start() if serviceconfig.isWin32() == True: for timer in self.timer: timer.join() else: activeThreads = [] for timer in self.timer: activeThreads.append(timer) while len(activeThreads) > 0: for timer in activeThreads: timer.join(10) activeThreads = [] for timer in self.timer: if timer.is_alive(): activeThreads.append(timer)
class RepeatingTimer(object): def __init__(self, interval, f, *args, **kwargs): self.interval = interval self.f = f self.args = args self.kwargs = kwargs self.timer = None def callback(self): self.f(*self.args, **self.kwargs) self.start() def cancel(self): self.timer.cancel() def start(self): self.timer = Timer(self.interval, self.callback) self.timer.start() def is_alive(self): if self.timer != None: return self.timer.is_alive() else: return False
def run_onionscan(self, onion): self.logger.info("[*] Running onionscan on %s", onion) # fire up onionscan process = subprocess.Popen([ self.onionscan, "--webport=0", "--jsonReport", "--simpleReport=false", onion ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # start the timer and let it run till timeout minutes process_timer = Timer(300, self.handle_timeout, args=[process, onion]) process_timer.start() # wait for the onion scan results stdout = process.communicate()[0] # we have received valid results so we can kill the timer if process_timer.is_alive(): process_timer.cancel() try: return self.response("success", json.loads(stdout), onion) except json.decoder.JSONDecodeError: pass self.logger.info("[!!!] Process timed out for %s", onion) return self.response("failure", None, onion)
def run_onionscan(onion): print("[*] Onionscanning %s" % onion) # fire up onionscan process = subprocess.Popen([ "onionscan", "--webport=0", "--jsonReport", "--simpleReport=false", onion ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # start the timer and let it run 5 minutes process_timer = Timer(300, handle_timeout, args=[process, onion]) process_timer.start() # wait for the onion scan results stdout = process.communicate()[0] # we have received valid results so we can kill the timer if process_timer.is_alive(): process_timer.cancel() return stdout print("[!!!] Process timed out!") return None
def base_solve(task): solver = g_solver(bootstrap_with=g_clauses, use_timer=True) if task.tl > 0: timer = Timer(task.tl, solver.interrupt, ()) timer.start() timestamp = now() status = solver.solve_limited(assumptions=task.get(), expect_interrupt=True) time = now() - timestamp if timer.is_alive(): timer.cancel() else: solver.clear_interrupt() else: timestamp = now() status = solver.solve(assumptions=task.get()) time = max(now() - timestamp, solver.time()) stats = solver.accum_stats() solution = solver.get_model() if status else None solver.delete() return task.resolve(status, time, stats, solution)
def _run_multienum(self): p = subprocess.Popen([enum_cmd], stdout=subprocess.PIPE, stdin=subprocess.PIPE, close_fds=True) if self.timeout: timed_out = False timer = Timer(self.timeout*60, lambda p: p.kill(), [p]) try: timer.start() output = p.communicate()[0].decode("utf-8") finally: if not timer.is_alive(): timed_out = True timer.cancel() if timed_out: raise TimeoutError('Enumeration took too long.') else: output = p.communicate()[0].decode("utf-8") count = 0 start_count = False for line in output.strip().split("\n"): if line.strip().endswith("RunTot"): start_count = True elif start_count and re.match(r"\d+\s+.*", line.strip()): count = int(line.split()[-1]) logger.debug("Enumeration resulted in {} structures".format(count)) return count
class PollerTimer: """Custom timer for the CanopenPoller. Args: time (int): Timeout to use for the timer. cb (function): Callback. """ def __init__(self, time, cb): self.cb = cb self.time = time self.thread = Timer(self.time, self.handle_function) def handle_function(self): """Handle method that creates the timer for the poller""" self.cb() self.thread = Timer(self.time, self.handle_function) self.thread.start() def start(self): """Starts the poller timer""" self.thread.start() def cancel(self): """Stops the poller timer""" self.thread.cancel() if self.thread.is_alive(): self.thread.join()
def _git_pull(self, repo_dir): logger.info("Git pull started.") cmd = 'git pull ' error = "" start_time = time.time() proc = subprocess.Popen(shlex.split(cmd), cwd=repo_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) timeout = conf.git.git_cmd_timeout timer = Timer(timeout, on_subprocess_timeout, [cmd, proc]) try: timer.start() (out, error) = proc.communicate() logger.debug("Cmd proc id: {}".format(proc.pid)) proc.wait() finally: if not timer.is_alive(): msg = "Git command '{}' timed out !!".format(cmd) logger.error(msg) # the word error must be in message error = "error:" + msg timer.cancel() # Special case for pull caller method will check the output if not self._is_error(error): logger.info("Git pull done " "(%.3f seconds)" % (time.time() - start_time)) return out, error
class MissedMessageWorker(QueueProcessingWorker): # Aggregate all messages received over the last BATCH_DURATION # seconds to let someone finish sending a batch of messages and/or # editing them before they are sent out as emails to recipients. # # The timer is running whenever; we poll at most every TIMER_FREQUENCY # seconds, to avoid excessive activity. # # TODO: Since this process keeps events in memory for up to 2 # minutes, it now will lose approximately BATCH_DURATION worth of # missed_message emails whenever it is restarted as part of a # server restart. We should probably add some sort of save/reload # mechanism for that case. TIMER_FREQUENCY = 5 BATCH_DURATION = 120 timer_event = None # type: Optional[Timer] events_by_recipient = defaultdict(list) # type: Dict[int, List[Dict[str, Any]]] batch_start_by_recipient = {} # type: Dict[int, float] def consume(self, event: Dict[str, Any]) -> None: logging.debug("Received missedmessage_emails event: %s" % (event,)) # When we process an event, just put it into the queue and ensure we have a timer going. user_profile_id = event['user_profile_id'] if user_profile_id not in self.batch_start_by_recipient: self.batch_start_by_recipient[user_profile_id] = time.time() self.events_by_recipient[user_profile_id].append(event) self.ensure_timer() def ensure_timer(self) -> None: if self.timer_event is not None: return self.timer_event = Timer(self.TIMER_FREQUENCY, MissedMessageWorker.maybe_send_batched_emails, [self]) self.timer_event.start() def stop_timer(self) -> None: if self.timer_event and self.timer_event.is_alive(): # type: ignore # Report mypy bug. self.timer_event.cancel() self.timer_event = None def maybe_send_batched_emails(self) -> None: self.stop_timer() current_time = time.time() for user_profile_id, timestamp in list(self.batch_start_by_recipient.items()): if current_time - timestamp < self.BATCH_DURATION: continue events = self.events_by_recipient[user_profile_id] logging.info("Batch-processing %s missedmessage_emails events for user %s" % (len(events), user_profile_id)) handle_missedmessage_emails(user_profile_id, events) del self.events_by_recipient[user_profile_id] del self.batch_start_by_recipient[user_profile_id] # By only restarting the timer if there are actually events in # the queue, we ensure this queue processor is idle when there # are no missed-message emails to process. if len(self.batch_start_by_recipient) > 0: self.ensure_timer()
def ping_server(self, ip=None): ping_ip = None if ip: ping_ip = ip elif self.server: ping_ip = self.server if ping_ip: ping_cmd = ['/bin/ping', '-c', str(self.count)] if self.ping_src_ip: ping_cmd.extend(['-I', self.ping_src_ip]) ping_cmd.append(str(ping_ip)) log.debug("ping linux cmd: %s", ' '.join(ping_cmd)) pping = subprocess.Popen(ping_cmd, stdout=subprocess.PIPE) time = Timer(self.timeout, pping.kill) time.start() out, _ = pping.communicate() if time.is_alive(): time.cancel() else: raise PingTimeout return out else: raise ValueError('IP was not defined')
def run_version(name, variant_id, variant_opts, logfile): '''Run benchmark name using command-line options variant_opts and record it as a Synquid variant variant_id in the results dictionary''' start = time.time() logfile.seek(0, os.SEEK_END) # Run Synquid on the benchmark, mute output: synquid = subprocess.Popen([SYNQUID_CMD] + COMMON_OPTS + variant_opts + [name + '.sq'], stdout=logfile, stderr=logfile) timer = Timer(TIMEOUT, lambda process: process.kill(), [synquid]) timer.start() stdout, stderr = synquid.communicate() end = time.time() is_timeout = not timer.is_alive() timer.cancel() print '{0:0.2f}'.format(end - start), if is_timeout: # Timeout print Back.RED + Fore.RED + Style.BRIGHT + 'TIMEOUT' + Style.RESET_ALL, results[name].variant_outcome[variant_id] = 'TIMEOUT' results[name].variant_times[variant_id] = -1 elif synquid.returncode: # Synthesis failed: record failure print Back.RED + Fore.RED + Style.BRIGHT + 'FAIL' + Style.RESET_ALL, results[name].variant_outcome[variant_id] = 'FAIL' results[name].variant_times[variant_id] = (end - start) else: # Synthesis succeeded: record time for variant print Back.GREEN + Fore.GREEN + Style.BRIGHT + 'OK' + Style.RESET_ALL, results[name].variant_outcome[variant_id] = 'OK' results[name].variant_times[variant_id] = (end - start)
class ThreadTimer(ITimer): def __init__(self, timeout=0): self.__timeout = timeout self.__active_flag = False self.__expired_flag = False self.__timer = None def start(self): self.__active_flag = True self.__expired_flag = False self.__timer = Timer(self.__timeout, self.__timerFunc) self.__timer.start() def restart(self): self.start() def stop(self): if self.__timer is not None: if self.__timer.is_alive(): self.__timer.cancel() def isExpired(self): return self.__expired_flag def isRunning(self): return self.__active_flag def __timerFunc(self): self.__expired_flag = True self.__active_flag = False
class WebCaptchaSelfDefinedClass: def __init__(self , cap=None): self.t = None self.cap = cap def open(self): interface = GUI() self.cap.release() cv2.destroyAllWindows() new=2 url='file://' + os.path.realpath('resources/index.html') webbrowser.open(url, new=new) interface.remove(isWorking) interface.add(isSuccess, x=20, y=20) print("Open webpage") def start(self, d=5): if not self.t: print("Timer initialized") gesture_status.config(text="Detected.. Please hold still" , width="100", fg='green', font=Trebuchet9bold) gesture_status.update_idletasks() self.t = Timer(d , self.open) self.t.start() def stop(self): if self.t and self.t.is_alive(): print("Timer is cancelled") gesture_status.config(text="Not detected..." , width="100", fg='red', font=Trebuchet9bold) gesture_status.update_idletasks() self.t.cancel() self.t = None
def get_osd_numbers(module, hostname, cluster_name, timeout): ''' Returns list of osd number. :param module: current module instance :param hostname: host on which module is being run on :param cluster_name: name of the Ceph cluster :param timeout: timeout the operation after specified number of seconds :return: list of osd numbers ''' cmd = ('ceph --cluster %s osd tree -f json' % (cluster_name)) p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, preexec_fn=os.setsid) t = Timer(timeout, kill_procgroup, [p]) t.start() output, err = p.communicate() if t.is_alive(): t.cancel() else: error_msg = "Timeout on cmd %s output %s" % (cmd, output) module.fail_json(msg=error_msg) if p.returncode != 0: error_msg = "Failed to run %s" % (cmd) module.fail_json(msg=error_msg) output = json.loads(output) osd_numbers = [] if output and 'nodes' in output: for entity in output['nodes']: if entity['type'] == 'host' and entity['name'] == hostname: osd_numbers = entity['children'][:] return osd_numbers
class MissedMessageWorker(QueueProcessingWorker): # Aggregate all messages received over the last BATCH_DURATION # seconds to let someone finish sending a batch of messages and/or # editing them before they are sent out as emails to recipients. # # The timer is running whenever; we poll at most every TIMER_FREQUENCY # seconds, to avoid excessive activity. # # TODO: Since this process keeps events in memory for up to 2 # minutes, it now will lose approximately BATCH_DURATION worth of # missed_message emails whenever it is restarted as part of a # server restart. We should probably add some sort of save/reload # mechanism for that case. TIMER_FREQUENCY = 5 BATCH_DURATION = 120 timer_event: Optional[Timer] = None events_by_recipient: Dict[int, List[Dict[str, Any]]] = defaultdict(list) batch_start_by_recipient: Dict[int, float] = {} def consume(self, event: Dict[str, Any]) -> None: logging.debug("Received missedmessage_emails event: %s", event) # When we process an event, just put it into the queue and ensure we have a timer going. user_profile_id = event['user_profile_id'] if user_profile_id not in self.batch_start_by_recipient: self.batch_start_by_recipient[user_profile_id] = time.time() self.events_by_recipient[user_profile_id].append(event) self.ensure_timer() def ensure_timer(self) -> None: if self.timer_event is not None: return self.timer_event = Timer(self.TIMER_FREQUENCY, MissedMessageWorker.maybe_send_batched_emails, [self]) self.timer_event.start() def stop_timer(self) -> None: if self.timer_event and self.timer_event.is_alive(): self.timer_event.cancel() self.timer_event = None def maybe_send_batched_emails(self) -> None: self.stop_timer() current_time = time.time() for user_profile_id, timestamp in list(self.batch_start_by_recipient.items()): if current_time - timestamp < self.BATCH_DURATION: continue events = self.events_by_recipient[user_profile_id] logging.info("Batch-processing %s missedmessage_emails events for user %s", len(events), user_profile_id) handle_missedmessage_emails(user_profile_id, events) del self.events_by_recipient[user_profile_id] del self.batch_start_by_recipient[user_profile_id] # By only restarting the timer if there are actually events in # the queue, we ensure this queue processor is idle when there # are no missed-message emails to process. if len(self.batch_start_by_recipient) > 0: self.ensure_timer()
def update_firmware(self, switch_name, firmware_url, downgrade, **kwargs): try: # connect to the switch and run the firmware upgrade procedure m7800_switch = SwitchMellanoxM7800(switch_name, **kwargs) m7800_switch.connect() # delete all stored images on the switch before sending ours over for image in m7800_switch.show_images().images_fetched_and_available: m7800_switch.image_delete(image = image.filename) m7800_switch.image_fetch(url = firmware_url) # install the firmware we just sent to the switch m7800_switch.install_firmware( # grab the filename from the switch on purpose in case it does something funky with it image = m7800_switch.show_images().images_fetched_and_available[0].filename ) # set the switch to boot from our installed image m7800_switch.image_boot_next() # perform extra downgrade steps if necessary if downgrade: # need to force a boot, even if the old code parsing the new configuration fails. m7800_switch.disable_fallback_reboot() m7800_switch.write_configuration() m7800_switch.reload() # now wait for the switch to come back. reconnected = False # timeout after 30 minutes. We use a no-op lambda because we just want to know when the timer expired. timer = Timer(1800, lambda: ()) timer.start() while timer.is_alive(): # swallow the expected exceptions while trying to connect to a switch that isn't ready yet. with suppress(SwitchException, ExpectMoreException): # use the switch as a context manager so every time the connect or factory reset fails, # we disconnect from the switch. with m7800_switch: m7800_switch.connect() # now factory reset the switch, which will reboot it again. # The successful connect above doesn't seem to guarantee that we can fire a # factory reset command, so we try in this loop. m7800_switch.factory_reset() timer.cancel() reconnected = True if not reconnected: raise CommandError( cmd = self.owner, msg = f'Unable to reconnect {switch_name} to switch while performing downgrade procedure.' ) else: m7800_switch.reload() # Turn some potentially verbose and detailed error messages into something more end user friendly # while keeping the dirty details available in the logs. except (SwitchException, ExpectMoreException) as exception: stack.commands.Log( message = f'Error during firmware update on {switch_name}: {exception}', level = syslog.LOG_ERR ) raise CommandError( cmd = self.owner, msg = f'Failed to update firmware on {switch_name}.' )
def _run_multienum(self): p = subprocess.Popen([enum_cmd], stdout=subprocess.PIPE, stdin=subprocess.PIPE, close_fds=True) if self.timeout: timed_out = False timer = Timer(self.timeout * 60, lambda p: p.kill(), [p]) try: timer.start() output = p.communicate()[0].decode("utf-8") finally: if not timer.is_alive(): timed_out = True timer.cancel() if timed_out: raise TimeoutError('Enumeration took too long.') else: output = p.communicate()[0].decode("utf-8") count = 0 start_count = False for line in output.strip().split("\n"): if line.strip().endswith("RunTot"): start_count = True elif start_count and re.match(r"\d+\s+.*", line.strip()): count = int(line.split()[-1]) logger.debug("Enumeration resulted in {} structures".format(count)) return count
def poll_touchscreen(events=1, timeout=10, stop_finger_up=False): """ Polling on the touchtest tool for a number of events or until the timeout expires :param events: number of events to poll until exit :param timeout: maximum poll time :return: a list of events in json format """ cmd = 'adb shell touchtest' proc = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE) timer = Timer(timeout, proc.kill) timer.start() events_structure = Touch_Events() index = 1 for line in iter(proc.stdout.readline, ''): if index >= events: if timer.is_alive(): timer.cancel() proc.kill() events_structure.extract_json(line) if stop_finger_up and events_structure.action[index-1] == "up": proc.kill() index += 1 if index == 1: print_to_console_and_logcat("No data results from touchtest poll") return None return events_structure
def solve_with(solver, assumptions, limits, expect_interrupt=False): if limits and limits.get('time_limit', 0) > 0: timer = Timer(limits['time_limit'], solver.interrupt, ()) timer.start() timestamp = now() status = solver.solve_limited(assumptions, expect_interrupt=True) time = now() - timestamp if timer.is_alive(): timer.cancel() del timer else: timestamp = now() if not expect_interrupt: status = solver.solve(assumptions) else: status = solver.solve_limited(assumptions, True) time = now() - timestamp if status is None: solver.clear_interrupt() solution = solver.get_model() if status else None statistics = {**solver.accum_stats(), 'time': time} return status, statistics, solution
class TimedRunner(): def __init__(self, interval, func): self.time_interval = interval self.func = func self.run = True def start(self): if self.run: self.func() self.thread = Timer(self.time_interval, self.start) self.thread.start() else: self.thread = None try: while self.thread and self.thread.is_alive(): self.thread.join(5) except KeyboardInterrupt: self.run = False # Hand the screen back to the terminal curses.endwin() # Exit thread sys.exit() def cancel(self): self.thread.cancel()
class TTNWatchdog(Exception): def __init__(self, timeout, telegram_bot, telegram_id): # timeout in seconds self.timeout = timeout self.telegram_bot = telegram_bot self.telegram_id = telegram_id self.timer = Timer(self.timeout, self.defaultHandler) self.timer.start() def start(self): try: self.timer.start() except: pass def stop(self): try: self.timer.cancel() except: pass def reset(self): if self.timer.is_alive() is False: nachricht = 'Got packets again' self.telegram_bot.send_message(self.telegram_id, nachricht) self.stop() self.timer = Timer(self.timeout, self.defaultHandler) self.start() def defaultHandler(self): nachricht = "Lost connection since {:.1f} Minutes".format( self.timeout / 60) self.telegram_bot.send_message(self.telegram_id, nachricht)
def worker_f(inst, init_sol, backdoor, count, tl): assumptions = [] for values in inst.values(solution=init_sol).values(): assumptions.extend(values) ans, statuses = None, [] variables = backdoor.snapshot() for value in range(count[0], count[1]): solver = Solver(bootstrap_with=inst.clauses()) values = [1 if value & (1 << i) else 0 for i in range(len(backdoor))][::-1] bd = [x if values[j] else -x for j, x in enumerate(variables)] timer = Timer(tl, solver.interrupt, ()) timer.start() timestamp = now() status = solver.solve_limited(assumptions=assumptions + bd) time = now() - timestamp if timer.is_alive(): timer.cancel() else: solver.clear_interrupt() solution = solver.get_model() if status else None statuses.append((value, status)) solver.delete() if status: ans = (solution, time) break return statuses, ans
def run_onionscan(onion): """ Creates a subprocess for the onionscan and then monitors the scan. A timer of 5 minutes (300) is defined. If the scan times out, the process is killed. :param onion: """ print(f"[*] Onionscanning {onion}") process = subprocess.Popen([ "onionscan", "-webport=0", "--jsonReport", "--simpleReport=false", onion ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) process_timer = Timer(300, handle_timeout, args=[process, onion]) process_timer.start() # wait for the onion scan results stdout = process.communicate()[0] # we have received valid results so we can kill the timer if process_timer.is_alive(): process_timer.cancel() return stdout else: print("[!!!] Process timed out!") return None
def run_onionscan(onion, identity_lock): """ :param onion: :param identity_lock: :return: """ print("[*] Onionscanning %s" % onion) # fire up onionscan process = subprocess.Popen(["/home/clement/.gvm/pkgsets/go1.4/global/bin/onionscan", "--jsonReport", "--simpleReport=false", onion], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # start the timer and let it run 5 minutes process_timer = Timer(300, handle_timeout, args=[process, onion, identity_lock]) process_timer.start() # wait for the onion scan results stdout = process.communicate()[0] # we have received valid results so we can kill the timer if process_timer.is_alive(): process_timer.cancel() return stdout print("[!!!] Process timed out!") return None
class BrewTimer: start_time = None timer = None duration = None def __init__(self, duration, function): """ Call a function after a specified duration :param duration: duration in seconds :param function: called after "duration" seconds :return: instance of BrewTimer """ self.duration = duration self.timer = Timer(self.duration, function) def start(self): self.start_time = datetime.now() self.timer.start() def cancel(self): self.timer.cancel() def alive(self): return self.timer.is_alive() def passed(self): if self.start_time: return (datetime.now() - self.start_time).total_seconds() return 0 def remaining(self): return self.duration - self.passed() def percentage(self): return int((self.passed() / self.duration) * 100)
class timer: def startTimer(self, n, func): self.stopTimer() self.t = Timer(n, func) self.t.start() def stopTimer(self): try: if self.t.is_alive(): self.t.cancel() except: pass
def runcode(code): try: tmpdir = tempfile.mkdtemp() tmpclass = getJavaFileName(code) if not tmpclass: print('<span style="color:red">Could not find class name in Java file! Do you have a public class in your code?</span>') return if tmpclass == "CustomSecurityManager" or "java" in tmpclass: print('<span style="color:red">Invalid class name!</span>') if len(code) > 10000: print('<span style="color:red">You have too much code! Please limit your code to be less than 10,000 characters.</span>') return filename = tmpdir + '/' + tmpclass + '.java' f = open(filename, 'w') f.write(code) f.close() jenv = os.environ.copy() appfolder = os.path.dirname(os.path.realpath(__file__)) jars = [] for jar in os.listdir(appfolder + "/web/libs"): if os.path.isfile(appfolder + "/web/libs/" + jar): jars.append(appfolder + "/web/libs/" + jar) shutil.copy(appfolder + "/Wrapper.java", tmpdir + "/Wrapper.java") p = subprocess.Popen(["javac", "-cp", ".:" + ":".join(jars), "Wrapper.java", filename], cwd=tmpdir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=jenv) outdata, errdata = p.communicate() if p.returncode != 0: print("<span style='color:red'>Error when compiling!</span>") if outdata: print(esc(outdata.decode('utf-8'))) if errdata: print("<span style='color:red'>" + esc(errdata.decode('utf-8')) + "</span>") shutil.rmtree(tmpdir) return if not os.path.isfile(tmpdir + "/" + tmpclass + ".class"): print("<span style='color:red'>No class file generated from compile step!</span>") shutil.rmtree(tmpdir) return p = subprocess.Popen(["java", "-Xmx128m", "-cp", ".:" + ":".join(jars), "Wrapper", tmpclass, ":".join([tmpdir, appfolder + "/web/libs/"])], cwd=tmpdir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=jenv) timer = Timer(TIMEOUT, p.kill) timer.start() outdata, errdata = p.communicate() if timer.is_alive(): timer.cancel() shutil.rmtree(tmpdir) print("<span style='color:green'>Program ran successfully!</span>") if outdata: print(esc(outdata.decode('utf-8'))) if errdata: print("<span style='color:red'>" + esc(errdata.decode('utf-8')) + "</span>") except Exception as e: print('<span style="color:red">Unknown error when running code!</span>\n', esc(str(e)))
class CommandManager(): def __init__(self): self.commandQueue = [] self.myTimer = Timer(0,self.main_loop) #Creates a new timer an starts it, delay is time until next command def create_new_timer(self): sleepTime = max(0,(self.commandQueue[0].executionTime - datetime.now()).total_seconds()) self.myTimer = Timer(sleepTime, self.main_loop) self.myTimer.start() #Executes the first command in the commandQueue and removes it from the queue def execute_command(self): cmd = self.commandQueue[0] self.commandQueue.remove(cmd) cmd.execute() def main_loop(self): if len(self.commandQueue) > 0: self.execute_command() if len(self.commandQueue) > 0: self.create_new_timer() #Enqueue a command object def enqueue_command(self, newCommand): newQueue = self.commandQueue for (i,cmd) in enumerate(newQueue): if newCommand.executionTime < cmd.executionTime: newQueue.insert(i, newCommand) #if insert at start if i==0: self.myTimer.cancel() self.create_new_timer() break else: newQueue.append(newCommand) if not self.myTimer.is_alive(): self.create_new_timer() self.commandQueue = newQueue #Delete a command, resets timer aswell def delete_command(self,cmdId): cmdToRemove = self.commandQueue[cmdId] self.commandQueue.remove(cmdToRemove) if len (self.commandQueue) > 0: self.create_new_timer()
class PerpetualTimer(object): """A timer wrapper class that repeats itself. """ def __init__(self, t, handler): self.t = t self.handler = handler self.thread = Timer(self.t, self.handle_function) def handle_function(self): self.handler() self.thread = Timer(self.t, self.handle_function) self.thread.setDaemon(True) self.thread.start() def start(self): self.thread.start() def cancel(self): if self.thread.is_alive(): self.thread.cancel()
def get_list_pkg_upgrades(module, timeout): cmd = "sudo aptitude -s -y upgrade" p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid) t = Timer(timeout, kill_procgroup, [p]) t.start() output, err = p.communicate() if t.is_alive(): t.cancel() else: error_msg = "Timeout on cmd %s output %s" % (cmd, output) module.fail_json(msg=error_msg) if p.returncode != 0: error_msg = "Failed to run %s" % (cmd) module.fail_json(msg=error_msg) output = output.splitlines() list_pkg_upgrades = [] UPGRADE_STR="The following packages will be upgraded:" RECOMMEND_STR="The following packages are RECOMMENDED but will NOT be installed:" idx_start_match = next((i for i, v in enumerate(output) if v == UPGRADE_STR), -1) if idx_start_match == -1: return list_pkg_upgrades idx_end_match = next((i for i, v in enumerate(output) if v == RECOMMEND_STR), -1) if idx_end_match == -1: idx_end_match = next((i for i, v in enumerate(output) if re.match('^\d*\s*packages upgraded.*not upgraded.$',v)), -1) if idx_end_match == -1: return list_pkg_upgrades for line in output[idx_start_match+1:idx_end_match]: list_pkg_upgrades.extend(line.split()) for pkg in list_pkg_upgrades: print "Pkg: %s" % pkg return list_pkg_upgrades
def run_onionscan(onion): print "[*] Onionscanning %s" % onion # fire up onionscan process = subprocess.Popen(["onionscan","--webport=0","--jsonReport","--simpleReport=false",onion],stdout=subprocess.PIPE,stderr=subprocess.PIPE) # start the timer and let it run 5 minutes process_timer = Timer(300,handle_timeout,args=[process,onion]) process_timer.start() # wait for the onion scan results stdout = process.communicate()[0] # we have received valid results so we can kill the timer if process_timer.is_alive(): process_timer.cancel() return stdout print "[!!!] Process timed out!" return None
class Heater(): def __init__(self,socket_number,tran_pin): self.heater_status = 0 self.socket_number = socket_number self.tran_pin = tran_pin #self.rc = rc_switch.Rcswitch(socket_number,tran_pin) def turn_on(self,runtime): #time in seconds runtime = float(runtime) self.runtime = runtime self.heater_start = time.time() webiopi.debug("heater will turn of in %d seconds" %runtime) self.heat_timer = Timer(self.runtime, self.turn_off) self.heat_timer.start() ret=call(["sudo python /home/pi/glados_interface/python/rc_send.py %s %s %s" % (str(self.tran_pin),"1",str(self.socket_number))],shell=True) if ret !=0: webiopi.debug("can't call rc_send") self.heater_status = 1 def turn_off(self): webiopi.debug("turning off heater....") ret=call(["sudo python /home/pi/glados_interface/python/rc_send.py %s %s %s" % (str(self.tran_pin),"0",str(self.socket_number))],shell=True) if ret !=0: webiopi.debug("can't call rc_send") if self.heater_status == 1: if self.heat_timer.is_alive(): webiopi.debug("Canceling Timer") self.heat_timer.cancel() webiopi.debug("TIMER IS NOW:") self.heater_status = 0 def elapsed_time(self): if self.heater_status == 0: return 0 else: elapsed = time.time() - self.heater_start #elapsed =16 sec sec_end = int(self.runtime - elapsed) #till end is runtime(e.g 9000sec) - elapsed(e.16sec) return sec_end
class MorseButton: """ Class to keep track of state variables for a morse code button. """ def __init__(self, button_pin=MORSE_PIN, buzzer_pin=BUZZER_PIN, led_pins=(R_PIN, G_PIN, B_PIN), tweet_timeout=5.0): """ Store pin, set up IO. """ self.button_pin = button_pin self.buzzer_pin = buzzer_pin self.tweet_timeout = tweet_timeout # Set up screen self.lcd = Adafruit_CharLCD() self.lcd.begin(16, 1) # Set up other GPIO pins # GPIO.setmode(GPIO.BCM) # LCD Library uses BCM GPIO.setup(self.button_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(self.buzzer_pin, GPIO.OUT) GPIO.output(self.buzzer_pin, GPIO.LOW) # turn buzzer OFF GPIO.add_event_detect(self.button_pin, GPIO.BOTH, callback=self.callback, bouncetime=25) self.led = RGBLEDPins(r=led_pins[0], g=led_pins[1], b=led_pins[2]) GPIO.setup(self.led.r, GPIO.OUT) GPIO.setup(self.led.g, GPIO.OUT) GPIO.setup(self.led.b, GPIO.OUT) # Set up state variables self.time_var = 0 self.curr_tweet = "" self.curr_letter = "" self.tweet_started = False self.last_button_state = False # Indicate everything is ready GPIO.output(self.led.g, GPIO.HIGH) print("Start Tweeting!") def handle_tweet(self): """ Function which handles out the current tweet. """ try: self.curr_tweet += morse.decode_letter(self.curr_letter) except morse.MorseCodeDecodeError as e: pass if len(self.curr_tweet) > 0: try: tweeting.send_tweet(self.curr_tweet) except twitter.api.TwitterHTTPError: print("Twitter Error, Try Again!") else: print("Empty Tweet, Try Again!") self.curr_tweet = "" self.curr_letter = "" self.tweet_started = False def light_change(self): """ Change the LED from indicating a dot to indicating a dash. """ GPIO.output(self.led.r, GPIO.LOW) GPIO.output(self.led.b, GPIO.HIGH) def loop(self): """ Handle any business which needs to be handled in a while True loop. """ self.lcd.clear() self.lcd.message(self.curr_tweet[-16:] + "\n") try: decoded = morse.decode_letter(self.curr_letter) except morse.MorseCodeDecodeError as e: # No letter or invalid letter, just display a block decoded = "*" self.lcd.message(self.curr_letter.ljust(15) + decoded) time.sleep(0.01667) # 60Hz? def callback(self, channel): """ Callback to handle button rising and falling edges. """ # Current state of the button is end edge of the transition. button_pressed = not GPIO.input(self.button_pin) if button_pressed == self.last_button_state: return self.last_button_state = button_pressed if button_pressed: # Button was just pressed. duration = millis() - self.time_var GPIO.output(self.buzzer_pin, GPIO.HIGH) self.light_timer = Timer(1.5 * DOT / 1000, self.light_change) self.light_timer.start() GPIO.output(self.led.g, GPIO.LOW) GPIO.output(self.led.r, GPIO.HIGH) # If the button was already pressed, record spaces, and restart the # tweet printing timer. if self.tweet_started: new_letter = DASH < duration <= 2.5 * DASH new_word = 2.5 * DASH < duration if new_letter or new_word: if new_word: self.curr_tweet += " " try: decoded = morse.decode_letter(self.curr_letter) self.curr_tweet += decoded except morse.MorseCodeDecodeError as e: print("Invalid Morse Code Character, Moving on") self.curr_letter = "" self.tweet_printer.cancel() self.tweet_printer = Timer(self.tweet_timeout, self.handle_tweet) self.tweet_printer.start() # If the tweet was not started, start it, and start the timeout. else: self.tweet_started = True self.tweet_printer = Timer(self.tweet_timeout, self.handle_tweet) self.tweet_printer.start() self.time_var = millis() # Keep track of press time. else: # Button was just released. duration = millis() - self.time_var GPIO.output(self.buzzer_pin, GPIO.LOW) if self.light_timer.is_alive(): self.light_timer.cancel() GPIO.output(self.led.r, GPIO.LOW) GPIO.output(self.led.b, GPIO.LOW) GPIO.output(self.led.g, GPIO.HIGH) # Determine if the duration held was a dot or a dash. if duration <= 1.5 * DOT: self.curr_letter += '.' else: self.curr_letter += '-' self.time_var = millis() # Keep track of release time.
class CMRESHandler(logging.Handler): """ Elasticsearch log handler Allows to log to elasticsearch into json format. All LogRecord fields are serialised and inserted """ class AuthType(Enum): """ Authentication types supported The handler supports - No authentication - Basic authentication - Kerberos or SSO authentication (on windows and linux) """ NO_AUTH = 0 BASIC_AUTH = 1 KERBEROS_AUTH = 2 # Defauls for the class __DEFAULT_HOST = [{'host': 'localhost', 'port': 9200}] __DEFAULT_AUTH_USER = '' __DEFAULT_AUTH_PASSWD = '' __DEFAULT_USE_SSL = False __DEFAULT_VERIFY_SSL = True __DEFAULT_AUTH_TYPE = AuthType.NO_AUTH __DEFAULT_BUFFER_SIZE = 1000 __DEFAULT_FLUSH_FREQUENCY_IN_SEC = 1 __DEFAULT_ADDITIONAL_FIELDS = {} __DEFAULT_ES_INDEX_NAME = 'python_logger' __DEFAULT_ES_DOC_TYPE = 'python_log' __DEFAULT_RAISE_ON_INDEXING_EXCEPTIONS = False __LOGGING_FILTER_FIELDS = ['msecs', 'relativeCreated', 'levelno', 'created'] def __init__(self, hosts=__DEFAULT_HOST, auth_details=(__DEFAULT_AUTH_USER, __DEFAULT_AUTH_PASSWD), auth_type=__DEFAULT_AUTH_TYPE, use_ssl=__DEFAULT_USE_SSL, verify_ssl=__DEFAULT_VERIFY_SSL, buffer_size=__DEFAULT_BUFFER_SIZE, flush_frequency_in_sec=__DEFAULT_FLUSH_FREQUENCY_IN_SEC, es_index_name=__DEFAULT_ES_INDEX_NAME, es_doc_type=__DEFAULT_ES_DOC_TYPE, es_additional_fields=__DEFAULT_ADDITIONAL_FIELDS, raise_on_indexing_exceptions=__DEFAULT_RAISE_ON_INDEXING_EXCEPTIONS): """ Handler constructor :param hosts: The list of hosts that elasticsearch clients will connect. The list can be provided in the format ```[{'host':'host1','port':9200}, {'host':'host2','port':9200}]``` to make sure the client supports failover of one of the instertion nodes :param auth_details: When ```CMRESHandler.AuthType.BASIC_AUTH``` is used this argument must contain a tuple of string with the user and password that will be used to authenticate against the Elasticsearch servers, for example```('User','Password') :param auth_type: The authentication type to be used in the connection ```CMRESHandler.AuthType``` Currently, NO_AUTH, BASIC_AUTH, KERBEROS_AUTH are supported :param use_ssl: A boolean that defines if the communications should use SSL encrypted communication :param verify_ssl: A boolean that defines if the SSL certificates are validated or not :param buffer_size: An int, Once this size is reached on the internal buffer results are flushed into ES :param flush_frequency_in_sec: A float representing how often and when the buffer will be flushed, even if the buffer_size has not been reached yet :param es_index_name: A string with the prefix of the elasticsearch index that will be created. Note a date with YYYY.MM.dd, ```python_logger``` used by default :param es_doc_type: A string with the name of the document type that will be used ```python_log``` used by default :param es_additional_fields: A dictionary with all the additional fields that you would like to add to the logs, such the application, environment, etc. :param raise_on_indexing_exceptions: A boolean, True only for debugging purposes to raise exceptions caused when :return: A ready to be used CMRESHandler. """ logging.Handler.__init__(self) self.hosts = hosts self.auth_details = auth_details, self.auth_type = auth_type self.use_ssl = use_ssl self.verify_certs = verify_ssl self.buffer_size = buffer_size self.flush_frequency_in_sec = flush_frequency_in_sec self.es_index_name = es_index_name self.es_doc_type = es_doc_type self.es_additional_fileds = es_additional_fields.copy() self.es_additional_fileds.update({'host': socket.gethostname(), 'host_ip': socket.gethostbyname(socket.gethostname())}) self.raise_on_indexing_exceptions = raise_on_indexing_exceptions self._buffer = [] self._timer = None self.__schedule_flush() def __schedule_flush(self): if self._timer is None: self._timer = Timer(self.flush_frequency_in_sec, self.flush) self._timer.setDaemon(True) self._timer.start() def __get_es_client(self): if self.auth_type == CMRESHandler.AuthType.NO_AUTH: return Elasticsearch(hosts=self.hosts, use_ssl=self.use_ssl, verify_certs=self.verify_certs, connection_class=RequestsHttpConnection) elif self.auth_type == CMRESHandler.AuthType.BASIC_AUTH: return Elasticsearch(hosts=self.hosts, http_auth=self.auth_details, use_ssl=self.use_ssl, verify_certs=self.verify_certs, connection_class=RequestsHttpConnection) elif self.auth_type == CMRESHandler.AuthType.KERBEROS_AUTH: return Elasticsearch(hosts=self.hosts, use_ssl=self.use_ssl, verify_certs=self.verify_certs, connection_class=RequestsHttpConnection( http_auth=HTTPKerberosAuth(mutual_authentication=DISABLED))) def test_es_source(self): """ Returns True if the handler can ping the Elasticsearch servers Can be used to confirm the setup of a handler has been properly done and confirm that things like the authentication is working properly :return: A boolean, True if the connection against elasticserach host was successful """ return self.__get_es_client().ping() def __get_es_index_name(self): """ Returns elasticearch index name :return: A srting containing the elasticsearch indexname used which should include the date. """ return "%s-%s" % (self.es_index_name, datetime.datetime.now().strftime('%Y.%m.%d')) @staticmethod def __get_es_datetime_str(timestamp): """ Returns elasticsearch utc formatted time for an epoch timestamp :param timestamp: epoch, including milliseconds :return: A string valid for elasticsearch time record """ t = datetime.datetime.utcfromtimestamp(timestamp) return "%s.%03.dZ" % (t.strftime('%Y-%m-%dT%H:%M:%S'), int(t.microsecond / 1000)) def flush(self): """ Flushes the buffer into ES :return: None """ if self._timer is not None and self._timer.is_alive(): self._timer.cancel() self._timer = None # FIXME: This should probably go on a different thread to speed up the execution if len(self._buffer) >= 0: try: actions = map(lambda x: {'_index': self.__get_es_index_name(), '_type': self.es_doc_type, '_source': x}, self._buffer) eshelpers.bulk(client=self.__get_es_client(), actions=actions, stats_only=True) except Exception as e: if self.raise_on_indexing_exceptions: raise e self._buffer = [] self.__schedule_flush() def close(self): """ Flushes the buffer and release any outstanding resource :return: None """ self.flush() self._timer.cancel() self._timer = None def emit(self, record): """ Emit overrides the abstract logging.Handler logRecord emit method records the log :param record: A class of type ```logging.LogRecord``` :return: None """ rec = self.es_additional_fileds.copy() for k, v in record.__dict__.items(): if k not in CMRESHandler.__LOGGING_FILTER_FIELDS: rec[k] = "" if v is None else v rec['timestamp'] = self.__get_es_datetime_str(record.created) self._buffer.append(rec) if len(self._buffer) >= self.buffer_size: self.flush()
def execute(): if executing: return try: subs = Submit.objects.filter(executed=False) if len(subs) == 0: return global executing executing = True for p in subs: p.is_executing = True p.save() p.output = "" p.comment = "" tests = TestProgram.objects.filter(problem=p.problem) legit = is_mathematica_code_legit(p.code) accomplishments = 0 if not legit: p.comment += "Użyto niedozwolonego słowa" else: for test in tests: hash = uuid4().hex TIK = uuid4().hex mathematica_input = ( "Developer`StartProtectedMode[]\n" + p.code + '\nPrint["BEGIN_TEST"];\n' + test.code.replace("TIK", TIK) + '\nPrint["' + hash + '"];' ) program = Popen(["wolfram"], stdout=PIPE, stdin=PIPE, stderr=PIPE) # p.output += mathematica_input timer = Timer(test.time, program.terminate) timer.start() output_data = program.communicate(input=bytes(mathematica_input, "UTF-8"))[0] fast_enough = False if timer.is_alive(): timer.cancel() fast_enough = True if not fast_enough: p.comment += "TEST " + str(test.id) + ": Przekroczono limit czasu" else: output = output_data.decode("utf-8") p.output += output tpos = output.rfind("BEGIN_TEST") output = output[tpos:] position = output.rfind("ACC:") if position == -1: p.comment += "TEST " + str(test.id) + ": BŁAD\n" else: accomplishment_string = output[position + 4 : position + 7] p.comment += "TEST " + str(test.id) + ": " if output.find(hash) == -1: p.comment += "Naruszono procedurę testowania\n" else: if accomplishment_string == "YES": accomplishments += 1 p.comment += "OK\n" else: p.comment += "BŁĄD\n" test_comments = findall("\(COMMENT:(.*?):COMMENT\)", output) for comment in test_comments: p.comment += "TEST " + str(test.id) + " komentarz: " + comment + "\n" p.accomplishment = accomplishments == len(tests) p.is_executing = False p.executed = True p.save() update_stats(p.user, p.problem) except: global executing executing = False global executing executing = False execute()
class NodeStatePublisher(object): """ Node state publisher. This class provides an interface to send heartbeat messages and specific error information. To use this class, simply instantiate it in your code. As soon as set_running() is called, the state publisher starts to send periodical heartbeat messages. To switch the state, call any of set_fatal(), set_error(), or set_recovering() for the respective state. Call set_running() again to return to the normal operation state. Only in this state the timestamp of the message is updated automatically. If you want to indicate aliveness, for example during recovering, call the respective set methods by yourself. @author Tim Niemueller """ def __init__(self, package_name, node_type): """ Constructor. @param package_name the name of the package that contains the node @param node_type the node type, this is the name of the executable, only the base name is used. """ self._state_pub = rospy.Publisher("/nodemon/state", NodeState) self._state_msg = NodeState() self._state_msg.nodename = rospy.get_name() self._state_msg.package = package_name self._state_msg.nodetype = os.path.basename(node_type) self._state_msg.state = NodeState.STARTING self._state_msg.time = rospy.Time.now() self._state_msg.machine_message = "" self._state_msg.human_message = "" self._timer = Timer(1.0, self.heartbeat_timer_cb) self._timer.start() def __del__(self): """ Destructor. """ if hasattr(self, "_timer") and self._timer.is_alive(): self._timer.cancel() def _publish_state(self): """Publish current state. """ self._state_pub.publish(self._state_msg) def set_running(self): """ Set the running state. The state publisher will start to send periodical heartbeat messages with updated time stamps. """ self._state_msg.state = NodeState.RUNNING self._state_msg.time = rospy.Time.now() self._state_msg.machine_message = "" self._state_msg.human_message = "" self._publish_state() def set_fatal(self, machine_msg, human_msg): """ Set the fatal state. The fatal state is meant for errors from which the node cannot recover without completely restarting it. The message should give a meaningful and concise description of the cause of the error. @param machine_msg message describing the cause of the fatal error in machine parseable format @param human_msg message describing the cause of the fatal error in human readable format """ self._state_msg.state = NodeState.FATAL self._state_msg.time = rospy.Time.now() self._state_msg.machine_message = machine_msg self._state_msg.human_message = human_msg self._publish_state() def set_error(self, machine_msg, human_msg): """ Set the non-fatal error state. The error state is meant for errors from which the node can recover at run-time. The node may require input from other nodes to start recovering, or it can start recovery by itself if possible and without risk of damaging the robot or harming humans. Once recovery is started, call set_recovering(). The message should give a meaningful and concise description of the cause of the error. @param machine_msg message describing the cause of the fatal error in machine parseable format @param human_msg message describing the cause of the fatal error in human readable format """ self._state_msg.state = NodeState.ERROR self._state_msg.time = rospy.Time.now() self._state_msg.machine_message = machine_msg self._state_msg.human_message = human_msg self._publish_state() def set_recovering(self, machine_msg, human_msg): """ Set recovering state. The recovery state is meant to describe that the node is in the process of returning to an operational state. During that time it cannot process any new requests or commands. Once recovery is finished call set_running() to indicate that the node is fully operational again. @param machine_msg a message describing the recovery method or procedure briefly in machine parseable format, e.g. "move_arm_safe_pos". @param machine_msg a message describing the recovery method or procedure briefly in human readable format, e.g. "moving arm to safe position". """ self._state_msg.state = NodeState.RECOVERING self._state_msg.time = rospy.Time.now() self._state_msg.machine_message = machine_msg self._state_msg.human_message = human_msg self._publish_state() def send_warning(self, machine_msg, human_msg): """ Send warning message. Warning messages are meant to indicate a serious problem to the developer or user, that the node was able to work around or solve this time, but that might also cause trouble. The warning message is modeled as a transitional state, i.e. an automatic transition is made back to the previous state after the warning has been processed. @param machine_msg a message describing the recovery method or procedure briefly in machine parseable format, e.g. "move_arm_safe_pos". @param machine_msg a message describing the recovery method or procedure briefly in human readable format, e.g. "moving arm to safe position". """ oldmsg = { "state": self._state_msg.state, "time": self._state_msg.time, "machine_message": self._state_msg.machine_message, "human_message": self._state_msg.human_message, } self._state_msg.state = NodeState.WARNING self._state_msg.time = rospy.Time.now() self._state_msg.machine_message = machine_msg self._state_msg.human_message = human_msg self._publish_state() self._state_msg.state = oldmsg["state"] self._state_msg.time = oldmsg["time"] self._state_msg.machine_message = oldmsg["machine_msg"] self._state_msg.human_message = oldmsg["human_msg"] self._publish_state() def heartbeat_timer_cb(self): """ Timer callback triggering status publishing. This function automatically restarts the time for as long as ros is not shutdown. """ if self._state_msg.state == NodeState.RUNNING: # we set the time automatically only when running! self._state_msg.time = rospy.Time.now() self._publish_state() if not rospy.is_shutdown(): self._timer = Timer(1.0, self.heartbeat_timer_cb) self._timer.start()
class MPManager(): dummyMsg='rebauth will guard your personal web informations' def __init__(self): self._browsers=[] self._MPH='' self._timer=None # from Client import MainWindow # self._main=mainWindow def evalConfidence(self,msg): ''' :return 0~4 : strength ''' return strength(msg)['score'] if len(msg) else 0 def login(self,hash): if type(hash) is str:hash=self.cryptor.hash(hash) DB=LocalDBConnector.Instance() config=DB.getConfig() # print(hash, DB.getConfig()) if config: if Cryptor(hash,config['CNT']).decrypt(config['dummy']) != self.dummyMsg: return False else: config={'CNT':getPrime(128),'dummy':'','MPexpire':5}#make new counter cryptor = Cryptor(hash, config['CNT']) #recreate cryptor with old counter if MP else create cryptor with new counter config['dummy']=cryptor.encrypt(self.dummyMsg) DB.updateConfig(config)#convert config to bytes for db and generate new dummy by encrypting again DB.socket.connect() self._MPH = hash self.mainView = WebBrowser(self) self._browsers.append(self.mainView) self.updateTimer(config['MPexpire']) return True def updateTimer(self,expireRate=None): ''' update timer counter for resetting MP expire on inputs ''' if expireRate is None: expireRate = LocalDBConnector.Instance().getConfig()['MPexpire'] self._timerCnt = expireRate self.mainView.setWindowTitle('RebAuth - Web [%d min]' % expireRate) if self._timer is None or not self._timer.is_alive(): self._timerTick(True) def _timerTick(self,init=False): ''' for each minute, expire MP or reset the 1 min timer ''' if self.mainView is None : return if not init: self._timerCnt -= 1 if self._timerCnt<=0: self._timer=None for browser in self._browsers: self.removeBrowser(browser) self._expireMP() return else: self.mainView.setWindowTitle('RebAuth - Web [%d min]' % self._timerCnt) if self._timer is not None and self._timer.is_alive(): self._timer.cancel() self._timer = Timer(60, self._timerTick, (False,)) self._timer.start() def removeBrowser(self, browser): try: self._browsers.remove(browser) except: pass if len(self._browsers) == 0: self._expireMP() #expire MP on all available browsers closed def getMPH(self): return self._MPH def _expireMP(self): self._MPH='' self._browsers.clear() self.mainView = None if self._timer: if self._timer.is_alive(): self._timer.cancel() from PyQt5.QtWidgets import QApplication, QWidget from Client.MainWindow import MainWindow # for w in QApplication.topLevelWindows(): # print(w.objectName()) for w in QApplication.topLevelWidgets(): # print(w.objectName()) if w.objectName() == 'MainWindow': w.show() break # mpManager = MPManager()
class Config(collections.MutableMapping): """Configuration JSON storage class""" def __init__(self, filename, default=None, failsafe_backups=0, save_delay=0): self.filename = filename self.default = None self.config = {} self.changed = False self.failsafe_backups = failsafe_backups self.save_delay = save_delay self.load() self._timer_save = False def _make_failsafe_backup(self): try: with open(self.filename) as f: json.load(f) except IOError: return False except ValueError: logger.warning("{} is corrupted, aborting backup".format(self.filename)) return False existing = sorted(glob.glob(self.filename + ".*.bak")) while len(existing) > (self.failsafe_backups - 1): os.remove(existing.pop(0)) backup_file = self.filename + "." + datetime.datetime.now().strftime("%Y%m%d%H%M%S") + ".bak" shutil.copy2(self.filename, backup_file) return True def _recover_from_failsafe(self): existing = sorted(glob.glob(self.filename + ".*.bak")) while len(existing) > 0: try: recovery_filename = existing.pop() with open(recovery_filename) as f: # test the file is valid json json.load(f) shutil.copy2(recovery_filename, self.filename) self.load(recovery=True) logger.info("recovery successful: {}".format(recovery_filename)) return True except IOError: pass except ValueError: logger.error("corrupted recovery: {}".format(self.filename)) return False def load(self, recovery=False): """Load config from file""" try: with open(self.filename) as f: self.config = json.load(f) logger.info("{} read".format(self.filename)) except IOError: self.config = {} except ValueError: if not recovery and self.failsafe_backups > 0 and self._recover_from_failsafe(): return raise self.changed = False def force_taint(self): self.changed = True def loads(self, json_str): """Load config from JSON string""" self.config = json.loads(json_str) self.changed = True def save(self, delay=True): if self.save_delay: if delay: if self._timer_save and self._timer_save.is_alive(): self._timer_save.cancel() self._timer_save = Timer(self.save_delay, self.save, [], {"delay": False}) self._timer_save.start() return False """Save config to file (only if config has changed)""" if self.changed: start_time = time.time() if self.failsafe_backups: self._make_failsafe_backup() with open(self.filename, 'w') as f: json.dump(self.config, f, indent=2, sort_keys=True) self.changed = False interval = time.time() - start_time logger.info("{} write {}".format(self.filename, interval)) return self.changed def flush(self): if self._timer_save and self._timer_save.is_alive(): logger.info("flushing {}".format(self.filename)) self._timer_save.cancel() self.save(delay=False) def get_by_path(self, keys_list): """Get item from config by path (list of keys)""" return functools.reduce(lambda d, k: d[int(k) if isinstance(d, list) else k], keys_list, self) def set_by_path(self, keys_list, value): """Set item in config by path (list of keys)""" self.get_by_path(keys_list[:-1])[keys_list[-1]] = value self.changed = True def pop_by_path(self, keys_list): popped_value = self.get_by_path(keys_list[:-1]).pop(keys_list[-1]) self.changed = True return popped_value def get_option(self, keyname): try: value = self.config[keyname] except KeyError: value = None return value def get_suboption(self, grouping, groupname, keyname): try: value = self.config[grouping][groupname][keyname] except KeyError: value = self.get_option(keyname) return value def exists(self, keys_list): _exists = True try: if self.get_by_path(keys_list) is None: _exists = False except (KeyError, TypeError): _exists = False return _exists def __getitem__(self, key): try: return self.config[key] except KeyError: return self.default def __setitem__(self, key, value): self.config[key] = value self.changed = True def __delitem__(self, key): del self.config[key] self.changed = True def __iter__(self): return iter(self.config) def __len__(self): return len(self.config)
def set_memory(self, eff_loss=0.1): """ Sets the recommended memory needed for a VASP calculation Code retrieves memory estimate based on the following priority: 1) DB file 2) existing OUTCAR 3) run partial diagnostic calculation The final method determines the memory requirements from KPOINT calculations run locally before submission to the queue returns the memory estimate from the OUTCAR file :param eff_loss: Estimated loss in computational efficiency when parallelizing over multiple processors. 10% is a safe upper bound from personal experience. :type eff_loss: float """ # Attempt to get the recommended memory from DB memory = self.get_db('memory') if memory is None: # Check if an OUTCAR exists from a previous run # WARNING: if calculation was run with > 1 ppn, estimate # in OUTCAR will reflect that recommended memory for that # number of ppn. This can lead to over-estimation of memory # requirements on calculations where set_required_memory # was not used initially. if os.path.exists(os.path.join(self.directory, 'OUTCAR')): memory = self.get_memory() # Write the recommended memory to the DB file self.write_db(data={'memory': memory}) # If no OUTCAR exists, we run a 'dummy' calculation else: try: original_ialgo = self.parameters['ialgo'] except(KeyError): original_ialgo = None self.set(ialgo=-1) # Generate the base files needed for VASP calculation from ase.calculators.calculator import FileIOCalculator FileIOCalculator.write_input(self, None, None, None) self.write_poscar() self.write_incar() if 'kspacing' not in self.parameters: self.write_kpoints() self.write_potcar() # Need to pass a function to Timer for delayed execution def kill(): process.kill() # We only need the memory estimate, so we can greatly # accelerate the process by terminating after we have it cwd = os.getcwd() os.chdir(self.directory) from subprocess import Popen, PIPE process = Popen(VASPRC['vasp.executable.serial'], stdout=PIPE) from threading import Timer import time timer = Timer(20.0, kill) timer.start() while True: if timer.is_alive(): memory = self.get_memory() if memory: timer.cancel() process.terminate() break else: time.sleep(0.1) else: raise RuntimeError('Memory estimate timed out') os.chdir(cwd) # return to original settings if original_ialgo: self.set(ialgo=original_ialgo) else: del self.parameters['ialgo'] self.write_incar() # Write the recommended memory to the DB file self.write_db(data={'memory': memory}) # Remove all non-initialization files files = ['CHG', 'CHGCAR', 'CONTCAR', 'DOSCAR', 'EIGENVAL', 'IBZKPT', 'OSZICAR', 'PCDAT', 'vasprun.xml', 'OUTCAR', 'WAVECAR', 'XDATCAR'] for f in files: os.unlink(os.path.join(self.directory, f)) # One node will require the memory read from the OUTCAR processors = VASPRC['queue.ppn'] + VASPRC['queue.nodes'] # Apply eff_loss if processors > 1: eff_factor = 1 + (eff_loss * float(processors)) # Rounded up to the nearest GB, and set the memory import math total_memory = int(math.ceil(eff_factor * float(memory))) VASPRC['queue.mem'] = '{0}GB'.format(total_memory) # Return the memory as read from the OUTCAR return memory
class Client(Frame): def __init__(self, addr, ID = ""): super(Client, self).__init__() self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.addr = addr self.ID = ID self.cleanSession = 0 self.pingThread = None self.connection = False self.messages = {} self.keepAlive = 2 self.subscribes = {} self.subTmp = [] self.unsubTmp = [] self.pingEvent = Event() def send(self, frame): self.sock.send(frame) def __recv(self, size = 1024): try: while self.connection: data = self.sock.recv(size) self.parseFrame(data, self) except Exception as e: # TODO: exception should be defined print e def connect(self, name = "", passwd = "", will = {}, clean = 0, keepAlive = 2): # TODO: above default value should be considered self.cleanSession = clean self.sock.connect(self.addr) self.connection = True self.keepAlive = keepAlive self.recvThread = Thread(target=self.__recv) self.recvThread.start() frame = self.makeFrame(TYPE.CONNECT, 0, 0, 0, name = name, passwd = passwd, will = will, clean = clean, cliID = self.ID, keepAlive = keepAlive) self.send(frame) def startSession(self): self.pingThread = Thread(target=self.__pingreq) self.pingThread.start() def disconnect(self): # NOTICE: sometimes this is called shoter than the keep alive time, # threading.Timer bug? if not self.connection: print("connection has already closed %s" % self.ID) return self.connection = False frame = self.makeFrame(TYPE.DISCONNECT, 0, 0, 0) self.send(frame) self.sock.close() print("disconnect %s" % self.ID) def publish(self, topic, message, dup = 0, qos = 0, retain = 0, messageID = 1): if (qos == 1 or qos == 2) and messageID == 0: #error, here pass if qos == 1 or qos == 2: # this stahds for unacknowledged state self.setState(["publish", topic, message, qos, retain], messageID, None) elif (qos == 0 or qos == 2) and dup: print("Warning: DUP flag should be 0 if QoS is set as %d" % qos) dup = 0 frame = self.makeFrame(TYPE.PUBLISH, dup, qos, retain, topic = topic, message = message, messageID = messageID) self.send(frame) def puback(self, messageID): self.messages.pop(messageID) def pubrec(self, messageID): self.messages.pop(messageID) def pubcomp(self, messageID): self.messages.pop(messageID) def setState(self, state, messageID, dummy): self.messages[messageID] = state def resend(self): for messageID in self.messages: state = self.messages[messageID] if state[0] == "publish": self.send(self.makeFrame(TYPE.PUBLISH, 1, state[3], state[4], topic = state[1], message = state[2], messageID = messageID)) elif state[0] == "pubrec": self.send(self.makeFrame(TYPE.PUBREC, 1, 0, 0, messageID = messageID)) elif state[0] == "pubrel": self.send(self.makeFrame(TYPE.PUBREL, 1, 1, 0, messageID = messageID)) def initTimer(self): self.timer.cancel() self.timer = Timer(self.keepAlive, self.disconnect) self.pingEvent.set() def __pingreq(self): self.timer = Timer(self.keepAlive, self.disconnect) try: while self.connection: # Q: continuously send req? or send after receiving resp? self.send(self.makeFrame(TYPE.PINGREQ, 0,0,0)) if not self.timer.is_alive(): self.timer.start() pingTime = time.time() self.pingEvent.wait(self.keepAlive * 2) # Is this timeout appropriate? time.sleep(self.keepAlive - (time.time() - pingTime)) except Exception as e: print e, self.ID pass def subscribe(self, topics, dup = 0, messageID = 1): # topics should be [[topic1, qos1], [topic2, qos2] ...] if len(topics) >= 2: qos = 1 elif len(topics) == 1: qos = 0 frame = self.makeFrame(TYPE.SUBSCRIBE, dup, qos, 0, topics = topics, messageID = messageID) self.send(frame) self.subTmp.append(topics) def setSubscribe(self, QoSs): tmp = self.subTmp.pop(0) for i in range(len(QoSs)): self.subscribes[tmp[i][0]] = QoSs[i] def unsubscribe(self, topics, dup = 0, messageID = 1): # topics should be [topic1, topic2 ...] if len(topics) >= 2: qos = 1 elif len(topics) == 1: qos = 0 frame = self.makeFrame(TYPE.UNSUBSCRIBE, dup, qos, 0, topics = topics, messageID = messageID) self.send(frame) self.unsubTmp.append(topics) def unsetSubscribe(self): tmp = self.unsubTmp.pop(0) for topic in tmp: self.subscribes.pop(topic)
def get_required_memory(self): ''' Returns the recommended memory needed for a VASP calculation Code retrieves memory estimate based on the following priority: 1) METADATA 2) existing OUTCAR 3) run diagnostic calculation The final method determines the memory requirements from KPOINT calculations run locally before submission to the queue ''' import json def get_memory(): ''' Retrieves the recommended memory from the OUTCAR ''' if os.path.exists('OUTCAR'): with open('OUTCAR') as f: lines = f.readlines() else: return None for line in lines: # There can be multiple instances of this, # but they all seem to be identical if 'memory' in line: # Read the memory usage required_mem = float(line.split()[-2]) / 1e6 return required_mem # Attempt to get the recommended memory from METADATA # JASP automatically generates a METADATA file when # run, so there should be no instances where it does not exist with open('METADATA', 'r') as f: data = json.load(f) try: memory = data['recommended.memory'] except(KeyError): # Check if an OUTCAR exists from a previous run if os.path.exists('OUTCAR'): memory = get_memory() # Write the recommended memory to the METADATA file with open('METADATA', 'r+') as f: data = json.load(f) data['recommended.memory'] = memory f.seek(0) json.dump(data, f) # If no OUTCAR exists, we run a 'dummy' calculation else: original_ialgo = self.int_params.get('ialgo') self.int_params['ialgo'] = -1 # Generate the base files needed for VASP calculation atoms = self.get_atoms() self.initialize(atoms) from ase.io.vasp import write_vasp write_vasp('POSCAR', self.atoms_sorted, symbol_count=self.symbol_count) self.write_incar(atoms) self.write_potcar() self.write_kpoints() self.write_sort_file() # We only need the memory estimate, so we can greatly # accelerate the process by terminating after we have it process = Popen(JASPRC['vasp.executable.serial'], stdout=PIPE) from threading import Timer timer = Timer(15.0, process.kill()) timer.start() while True: if timer.is_alive(): memory = get_memory() if memory: timer.cancel() process.terminate() break else: raise RuntimeError('Memory estimate timed out') # return to original settings self.int_params['ialgo'] = original_ialgo self.write_incar(atoms) # Write the recommended memory to the METADATA file with open('METADATA', 'r+') as f: data = json.load(f) data['recommended.memory'] = memory f.seek(0) json.dump(data, f) # Remove all non-initialization files files = ['CHG', 'CHGCAR', 'CONTCAR', 'DOSCAR', 'EIGENVAL', 'IBZKPT', 'OSZICAR', 'PCDAT', 'vasprun.xml', 'OUTCAR', 'WAVECAR', 'XDATCAR'] for f in files: os.unlink(f) # Each node will require the memory read from the OUTCAR nodes = JASPRC['queue.nodes'] ppn = JASPRC['queue.ppn'] # Return an integer import math total_memory = int(math.ceil(nodes * ppn * memory)) JASPRC['queue.mem'] = '{0}GB'.format(total_memory) # return the memory as read from the OUTCAR return memory
class CMRESHandler(logging.Handler): """ Elasticsearch log handler Allows to log to elasticsearch into json format. All LogRecord fields are serialised and inserted """ class AuthType(Enum): """ Authentication types supported The handler supports - No authentication - Basic authentication - Kerberos or SSO authentication (on windows and linux) """ NO_AUTH = 0 BASIC_AUTH = 1 KERBEROS_AUTH = 2 AWS_SIGNED_AUTH = 3 class IndexNameFrequency(Enum): """ Index type supported the handler supports - Daily indices - Weekly indices - Monthly indices - Year indices """ DAILY = 0 WEEKLY = 1 MONTHLY = 2 YEARLY = 3 # Defaults for the class __DEFAULT_ELASTICSEARCH_HOST = [{'host': 'localhost', 'port': 9200}] __DEFAULT_AUTH_USER = '' __DEFAULT_AUTH_PASSWD = '' __DEFAULT_AWS_ACCESS_KEY = '' __DEFAULT_AWS_SECRET_KEY = '' __DEFAULT_AWS_REGION = '' __DEFAULT_USE_SSL = False __DEFAULT_VERIFY_SSL = True __DEFAULT_AUTH_TYPE = AuthType.NO_AUTH __DEFAULT_INDEX_FREQUENCY = IndexNameFrequency.DAILY __DEFAULT_BUFFER_SIZE = 1000 __DEFAULT_FLUSH_FREQ_INSEC = 1 __DEFAULT_ADDITIONAL_FIELDS = {} __DEFAULT_ES_INDEX_NAME = 'python_logger' __DEFAULT_ES_DOC_TYPE = 'python_log' __DEFAULT_RAISE_ON_EXCEPTION = False __DEFAULT_TIMESTAMP_FIELD_NAME = "timestamp" __LOGGING_FILTER_FIELDS = ['msecs', 'relativeCreated', 'levelno', 'created'] @staticmethod def _get_daily_index_name(es_index_name): """ Returns elasticearch index name :param: index_name the prefix to be used in the index :return: A srting containing the elasticsearch indexname used which should include the date. """ return "{0!s}-{1!s}".format(es_index_name, datetime.datetime.now().strftime('%Y.%m.%d')) @staticmethod def _get_weekly_index_name(es_index_name): """ Return elasticsearch index name :param: index_name the prefix to be used in the index :return: A srting containing the elasticsearch indexname used which should include the date and specific week """ current_date = datetime.datetime.now() start_of_the_week = current_date - datetime.timedelta(days=current_date.weekday()) return "{0!s}-{1!s}".format(es_index_name, start_of_the_week.strftime('%Y.%m.%d')) @staticmethod def _get_monthly_index_name(es_index_name): """ Return elasticsearch index name :param: index_name the prefix to be used in the index :return: A srting containing the elasticsearch indexname used which should include the date and specific moth """ return "{0!s}-{1!s}".format(es_index_name, datetime.datetime.now().strftime('%Y.%m')) @staticmethod def _get_yearly_index_name(es_index_name): """ Return elasticsearch index name :param: index_name the prefix to be used in the index :return: A srting containing the elasticsearch indexname used which should include the date and specific year """ return "{0!s}-{1!s}".format(es_index_name, datetime.datetime.now().strftime('%Y')) _INDEX_FREQUENCY_FUNCION_DICT = { IndexNameFrequency.DAILY: _get_daily_index_name, IndexNameFrequency.WEEKLY: _get_weekly_index_name, IndexNameFrequency.MONTHLY: _get_monthly_index_name, IndexNameFrequency.YEARLY: _get_yearly_index_name } def __init__(self, hosts=__DEFAULT_ELASTICSEARCH_HOST, auth_details=(__DEFAULT_AUTH_USER, __DEFAULT_AUTH_PASSWD), aws_access_key=__DEFAULT_AWS_ACCESS_KEY, aws_secret_key=__DEFAULT_AWS_SECRET_KEY, aws_region=__DEFAULT_AWS_REGION, auth_type=__DEFAULT_AUTH_TYPE, use_ssl=__DEFAULT_USE_SSL, verify_ssl=__DEFAULT_VERIFY_SSL, buffer_size=__DEFAULT_BUFFER_SIZE, flush_frequency_in_sec=__DEFAULT_FLUSH_FREQ_INSEC, es_index_name=__DEFAULT_ES_INDEX_NAME, index_name_frequency=__DEFAULT_INDEX_FREQUENCY, es_doc_type=__DEFAULT_ES_DOC_TYPE, es_additional_fields=__DEFAULT_ADDITIONAL_FIELDS, raise_on_indexing_exceptions=__DEFAULT_RAISE_ON_EXCEPTION, default_timestamp_field_name=__DEFAULT_TIMESTAMP_FIELD_NAME): """ Handler constructor :param hosts: The list of hosts that elasticsearch clients will connect. The list can be provided in the format ```[{'host':'host1','port':9200}, {'host':'host2','port':9200}]``` to make sure the client supports failover of one of the instertion nodes :param auth_details: When ```CMRESHandler.AuthType.BASIC_AUTH``` is used this argument must contain a tuple of string with the user and password that will be used to authenticate against the Elasticsearch servers, for example```('User','Password') :param aws_access_key: When ```CMRESHandler.AuthType.AWS_SIGNED_AUTH``` is used this argument must contain the AWS key id of the the AWS IAM user :param aws_secret_key: When ```CMRESHandler.AuthType.AWS_SIGNED_AUTH``` is used this argument must contain the AWS secret key of the the AWS IAM user :param aws_region: When ```CMRESHandler.AuthType.AWS_SIGNED_AUTH``` is used this argument must contain the AWS region of the the AWS Elasticsearch servers, for example```'us-east' :param auth_type: The authentication type to be used in the connection ```CMRESHandler.AuthType``` Currently, NO_AUTH, BASIC_AUTH, KERBEROS_AUTH are supported :param use_ssl: A boolean that defines if the communications should use SSL encrypted communication :param verify_ssl: A boolean that defines if the SSL certificates are validated or not :param buffer_size: An int, Once this size is reached on the internal buffer results are flushed into ES :param flush_frequency_in_sec: A float representing how often and when the buffer will be flushed, even if the buffer_size has not been reached yet :param es_index_name: A string with the prefix of the elasticsearch index that will be created. Note a date with YYYY.MM.dd, ```python_logger``` used by default :param index_name_frequency: Defines what the date used in the postfix of the name would be. available values are selected from the IndexNameFrequency class (IndexNameFrequency.DAILY, IndexNameFrequency.WEEKLY, IndexNameFrequency.MONTHLY, IndexNameFrequency.YEARLY). By default it uses daily indices. :param es_doc_type: A string with the name of the document type that will be used ```python_log``` used by default :param es_additional_fields: A dictionary with all the additional fields that you would like to add to the logs, such the application, environment, etc. :param raise_on_indexing_exceptions: A boolean, True only for debugging purposes to raise exceptions caused when :return: A ready to be used CMRESHandler. """ logging.Handler.__init__(self) self.hosts = hosts self.auth_details = auth_details self.aws_access_key = aws_access_key self.aws_secret_key = aws_secret_key self.aws_region = aws_region self.auth_type = auth_type self.use_ssl = use_ssl self.verify_certs = verify_ssl self.buffer_size = buffer_size self.flush_frequency_in_sec = flush_frequency_in_sec self.es_index_name = es_index_name self.index_name_frequency = index_name_frequency self.es_doc_type = es_doc_type self.es_additional_fields = es_additional_fields.copy() self.es_additional_fields.update({'host': socket.gethostname(), 'host_ip': socket.gethostbyname(socket.gethostname())}) self.raise_on_indexing_exceptions = raise_on_indexing_exceptions self.default_timestamp_field_name = default_timestamp_field_name self._client = None self._buffer = [] self._buffer_lock = Lock() self._timer = None self._index_name_func = CMRESHandler._INDEX_FREQUENCY_FUNCION_DICT[self.index_name_frequency] self.serializer = CMRESSerializer() def __schedule_flush(self): if self._timer is None: self._timer = Timer(self.flush_frequency_in_sec, self.flush) self._timer.setDaemon(True) self._timer.start() def __get_es_client(self): if self.auth_type == CMRESHandler.AuthType.NO_AUTH: if self._client is None: self._client = Elasticsearch(hosts=self.hosts, use_ssl=self.use_ssl, verify_certs=self.verify_certs, connection_class=RequestsHttpConnection, serializer=self.serializer) return self._client if self.auth_type == CMRESHandler.AuthType.BASIC_AUTH: if self._client is None: return Elasticsearch(hosts=self.hosts, http_auth=self.auth_details, use_ssl=self.use_ssl, verify_certs=self.verify_certs, connection_class=RequestsHttpConnection, serializer=self.serializer) return self._client if self.auth_type == CMRESHandler.AuthType.KERBEROS_AUTH: if not CMR_KERBEROS_SUPPORTED: raise EnvironmentError("Kerberos module not available. Please install \"requests-kerberos\"") # For kerberos we return a new client each time to make sure the tokens are up to date return Elasticsearch(hosts=self.hosts, use_ssl=self.use_ssl, verify_certs=self.verify_certs, connection_class=RequestsHttpConnection, http_auth=HTTPKerberosAuth(mutual_authentication=DISABLED), serializer=self.serializer) if self.auth_type == CMRESHandler.AuthType.AWS_SIGNED_AUTH: if not AWS4AUTH_SUPPORTED: raise EnvironmentError("AWS4Auth not available. Please install \"requests-aws4auth\"") if self._client is None: awsauth = AWS4Auth(self.aws_access_key, self.aws_secret_key, self.aws_region, 'es') self._client = Elasticsearch( hosts=self.hosts, http_auth=awsauth, use_ssl=self.use_ssl, verify_certs=True, connection_class=RequestsHttpConnection, serializer=self.serializer ) return self._client raise ValueError("Authentication method not supported") def test_es_source(self): """ Returns True if the handler can ping the Elasticsearch servers Can be used to confirm the setup of a handler has been properly done and confirm that things like the authentication is working properly :return: A boolean, True if the connection against elasticserach host was successful """ return self.__get_es_client().ping() @staticmethod def __get_es_datetime_str(timestamp): """ Returns elasticsearch utc formatted time for an epoch timestamp :param timestamp: epoch, including milliseconds :return: A string valid for elasticsearch time record """ current_date = datetime.datetime.utcfromtimestamp(timestamp) return "{0!s}.{1:03d}Z".format(current_date.strftime('%Y-%m-%dT%H:%M:%S'), int(current_date.microsecond / 1000)) def flush(self): """ Flushes the buffer into ES :return: None """ if self._timer is not None and self._timer.is_alive(): self._timer.cancel() self._timer = None if self._buffer: try: with self._buffer_lock: logs_buffer = self._buffer self._buffer = [] actions = ( { '_index': self._index_name_func.__func__(self.es_index_name), '_type': self.es_doc_type, '_source': log_record } for log_record in logs_buffer ) eshelpers.bulk( client=self.__get_es_client(), actions=actions, stats_only=True ) except Exception as exception: if self.raise_on_indexing_exceptions: raise exception def close(self): """ Flushes the buffer and release any outstanding resource :return: None """ if self._timer is not None: self.flush() self._timer = None def emit(self, record): """ Emit overrides the abstract logging.Handler logRecord emit method Format and records the log :param record: A class of type ```logging.LogRecord``` :return: None """ self.format(record) rec = self.es_additional_fields.copy() for key, value in record.__dict__.items(): if key not in CMRESHandler.__LOGGING_FILTER_FIELDS: if key == "args": value = tuple(str(arg) for arg in value) rec[key] = "" if value is None else value rec[self.default_timestamp_field_name] = self.__get_es_datetime_str(record.created) with self._buffer_lock: self._buffer.append(rec) if len(self._buffer) >= self.buffer_size: self.flush() else: self.__schedule_flush()
class ColorBot: def __init__(self): if __name__ != "__main__": raise BotException("ColorBot must run in the main module") self.started = False self.postInterval = 2 self.postQueue = [] #Update data self.updateInterval = 60 #The goal image self.goalImage = None #Data for grabbing incoming posts from twitter self.incomingQueue = [] self.lastIncomingId = 427546836853735424 #Image processing Worker Queue self.imageWorkers = [] self.continueWork = False self.workerCount = 5 #Store the best submission this round self.bestPost = None self.bestDistance = sys.float_info.max self.lastPost = "" self.lastPostTime = 0 self.printLock = RLock() self.post_lock = RLock() self.data_lock = RLock() #Blocks until bot exits def startBot(self): self.logInfo("Starting ThreadedBot.") self.started = True try: self.twitter_acnt = Twython( Configs.consumer_key, Configs.consumer_secret, Configs.access_token_key, Configs.access_token_secret) except: raise self.roundThread = None self.updateThread = None while True: console_input = raw_input("--> ").lower() input_responses = { 'startround': (self.startRound, []), 'exitbot': (self.stopBot, []), 'printlastpost': (self.printLastPost, []), 'endround': (self.endRound, []) } response = input_responses.get(console_input, (bot.inputError, [])) print str(response) try: directive = response[0](*response[1]) except BotException as e: if e.value == "Unrecognized Command.": print "Unrecognized Command." continue else: raise if directive == "kill": break elif directive != None: print str(directive) def startRound(self): filename = raw_input("image filename: ") post_text = raw_input("post text: ") round_len = raw_input("round length: ") bestDistance = sys.float_info.max bestPost = None try: round_len = int(round_len) except: print "Can't convert to integer." return None try: im = Image.open(filename) except: print "Can't open image: " + str(sys.exc_info()[0]) return None #Set the last known id to the ID of the starting post. self.lastIncomingId = self.makePost(post=str(post_text), media=im) self.goalImage = im self.clearRoundData() self.restartUpdateThread() self.startWorkerQueue() self.killRoundThread() self.roundThread = Timer(round_len, self.endRound) self.roundThread.start() def clearRoundData(self): self.stopWorkerQueue() with self.data_lock: self.bestImage = None self.imageQueue = [] def startWorkerQueue(self): self.logInfo("Start Worker Queue") self.continueWork = True for i in range(0,self.workerCount): newWorker = Thread(target=self.processImageFromQueue) self.imageWorkers.append(newWorker) newWorker.start() def stopWorkerQueue(self): self.logInfo("Stop worker queue") self.continueWork = False #Do something to stop the worker queue for worker in self.imageWorkers: worker.join() self.imageWorkers = [] def processImageFromQueue(self): while self.continueWork: myPost = None with self.data_lock: if len(self.incomingQueue) > 0: self.logInfo("Gonna get a post") myPost = self.incomingQueue.pop(0) else: continue if self.goalImage == None: continue self.logInfo("Start processing image") #result = Get Post and result if myPost != None: url = self.extractImageUrl(myPost) image_data = urllib2.urlopen(url).read() im = Image.open(BytesIO(image_data)) try: result = ColorPicker.getColorDiff(im, self.goalImage) except: self.logError("Error decoding posted image." + str(sys.exc_info()[0])) traceback.print_exc() continue with self.data_lock: if(result < self.bestDistance): self.logInfo("New best distance: " + str(result)) self.bestDistance = result self.bestPost = myPost else: self.logInfo("Not quite good enough.") self.logInfo("Done processing.") def getPostsFromTwitter(self): self.logInfo("Get posts from twitter") if self.lastIncomingId == None: self.logError("Don't have the last incoming tweet set") return None mention_posts = self.twitter_acnt.get_mentions_timeline(since_id=self.lastIncomingId) count = 0 for post in mention_posts: if self.extractImageUrl(post) != None: with self.data_lock: count += 1 self.incomingQueue.append(post) post_id = self.extractPostId(post) if post_id != None: self.lastIncomingId = post_id self.logInfo("Got " + str(count) + " posts") self.restartUpdateThread() def restartUpdateThread(self): if self.updateThread: self.updateThread.cancel() if currentThread() != self.updateThread and self.updateThread.is_alive(): try: self.updateThread.join() except RuntimeError as e: self.logError("RuntimeError stopping updateThread: " + str(e)) self.updateThread = None self.updateThread = Timer(self.updateInterval, self.getPostsFromTwitter) self.updateThread.start() def endRound(self): self.killRoundThread() if self.bestPost != None: post_text = "We have a winnder! @" + str(self.extractUsername(self.bestPost)) + " with their image " url = self.extractImageUrl(self.bestPost) image_data = urllib2.urlopen(url).read() im = Image.open(BytesIO(image_data)) self.makePost(post=str(post_text), media=im) else: self.logInfo("No submissions.") self.makePost(post="The round's over but no one submitted :-( Come on #GGJ14 and #SFGGJ14!") def killRoundThread(self): if self.roundThread: self.roundThread.cancel() if currentThread() != self.roundThread and self.roundThread.is_alive(): try: self.roundThread.join() except RuntimeError as e: self.logError("RuntimeError stopping roundThread: " + str(e)) self.roundThread = None def makePost(self, post, media=None): if not self.started: raise BotException("Bot not started.") with self.post_lock, self.data_lock: try: self.logInfo("post text = " + str(post)) if media != None: media.save('image.png') imageData = open('image.png', "rb") response = self.twitter_acnt.update_status_with_media(status=post, media=imageData) else: response = self.twitter_acnt.update_status(status=post) if response != None: if "id" in response: return response["id"] else: return None except TwythonError as e: self.logError("Trython error posting tweet: " + str(e)) traceback.print_exc() except NameError as e: self.logError("NameError error posting tweet: " + str(e)) traceback.print_exc() except AttributeError as e: self.logError("AttributeError error posting tweet: " + str(e)) traceback.print_exc() except: self.logError("Unexpected error posting tweet: " + str(sys.exc_info()[0])) traceback.print_exc() return None def extractImageUrl(self, post): entities = None media = None url = None if "entities" in post: entities = post["entities"] if "media" in entities: media = entities["media"] if media != None and len(media) > 0 and "media_url_https" in media[0]: url = media[0]["media_url_https"] return url def extractUsername(self, post): user = None screen_name = None if "user" in post: user = post["user"] if "screen_name" in user: screen_name = user["screen_name"] return screen_name def extractPostId(self, post): if "id" in post: return post["id"] return None def printLastPost(self): if not self.started: raise BotException("Bot not started.") with self.postLock: return str("Last Post: " + self.lastPost) def flushQueue(self): if not self.started: raise BotException("Bot not started.") with self.data_lock: self.logInfo(str("Flushing the Queue")) return "Queue Flushed" def stopBot(self): if not self.started: raise BotException("Bot not started.") self.logInfo(str("Stopping Bot")) print "Stopping Bot" self.stopWorkerQueue() with self.post_lock, self.data_lock: self.logInfo(str("Waiting on updateThread to terminate.")) if self.updateThread != None: self.updateThread.cancel() self.logInfo(str("Waiting on roundThread to terminate.")) if self.roundThread != None: self.roundThread.cancel() if self.updateThread != None and self.updateThread.is_alive(): try: self.updateThread.join() except RuntimeError as e: self.logError("RuntimeError stopping updateThread: " + str(e)) if self.roundThread != None and self.roundThread.is_alive(): try: self.roundThread.join() except RuntimeError as e: self.logError("RuntimeError stopping roundThread: " + str(e)) self.updateThread = None self.roundThread = None return "kill" def logInfo(self, message): with self.printLock: logging.info(str(datetime.now().strftime(" %Y-%m-%d %H:%M:%S: ")) + str(message)) def logError(self, message): with self.printLock: logging.error(str(datetime.now().strftime(" %Y-%m-%d %H:%M:%S: ")) + str(message)) def inputError(self): raise BotException("Unrecognized Command.")
class Console: def __init__(self, screen_width, screen_height): self.idle_timer = Timer(30, self.go_idle) self.screen = pygame.display.set_mode((screen_width, screen_height)) self.init_default_cfg() self.rect = pygame.Rect(self.screen.get_rect()) self.rect.size = self.screen.get_size() self.size = self.screen.get_size() self.bg_layer = pygame.Surface(self.size) self.bg_layer.set_alpha(self.bg_alpha) self.txt_layer = pygame.Surface(self.size) self.txt_layer.set_colorkey(self.bg_color) self.font_size = 62 self.font = pygame.font.SysFont('droidserif.ttf', self.font_size) self.font_height = self.font.get_linesize() self.max_lines = (self.size[HEIGHT] / self.font_height) self.c_out = '' self.c_pos = 0 self.c_draw_pos = 0 self.c_scroll = 0 self.changed = True def init_default_cfg(self): self.bg_alpha = 255 self.bg_color = [0xFF, 0xFF, 0xFF] self.txt_color_i = [0x0, 0x0, 0x0] self.txt_color_o = [0x0, 0x0, 0x0] self.lines = [] def new_twitchmessage(self, ucolor, displayname, emotes, subscriber, turbo, usertype, username, channel, message): if self.idle_timer.is_alive(): self.idle_timer.cancel() prepends = '' if usertype == 'mod': prepends = '@' + prepends elif usertype: prepends = '^' + usertype + '^_' + prepends if subscriber: prepends = '$' + prepends prepends = '['+channel[:3]+']' + prepends before_message = '%s%s : ' % (prepends, displayname or username) wrapped = wraptext(before_message + message, self.font, self.size[WIDTH]) first_line = wrapped[0] prepends_surf = self.font.render(prepends, True, self.txt_color_o) if ucolor: username_surf = self.font.render(displayname or username, True, (int(ucolor[:2], 16), int(ucolor[2:4], 16), int(ucolor[4:], 16))) else: username_surf = self.font.render(displayname or username, True, self.txt_color_o) filler_surf = self.font.render(' : ', True, self.txt_color_o) message_surf = self.font.render(first_line[len(before_message):], True, self.txt_color_o) self.lines.append([prepends_surf, username_surf, filler_surf, message_surf]) for wrappedline in wrapped[1:]: self.lines.append(self.font.render(wrappedline, True, self.txt_color_o)) self.prepare_display() self.txt_layer.fill(self.bg_color) lines = self.lines[-(self.max_lines+self.c_scroll):len(self.lines)-self.c_scroll] y_pos = self.size[HEIGHT]-(self.font_height*(len(lines))) for line in lines: if isinstance(line, list): x_pos = 0 for part in line: self.txt_layer.blit(part, (x_pos, y_pos, 0, 0)) x_pos += part.get_width() else: self.txt_layer.blit(line, (0, y_pos, 0, 0)) y_pos += self.font_height self.bg_layer.fill(self.bg_color) self.bg_layer.blit(self.txt_layer, (0, 0, 0, 0)) pygame.draw.rect(self.screen, self.txt_color_i, (self.rect.x - 1, self.rect.y - 1, self.size[WIDTH] + 2, self.size[HEIGHT] + 2), 1) self.screen.blit(self.bg_layer, self.rect) pygame.display.update() self.idle_timer = Timer(60 * 10, self.go_idle) self.idle_timer.start() return def prepare_display(self): if not pygame.display.get_init(): turn_screen_on() pygame.display.init() self.screen = pygame.display.set_mode((self.size[WIDTH], self.size[HEIGHT])) self.rect = pygame.Rect(self.screen.get_rect()) def go_idle(self): turn_screen_off() pygame.display.quit()
class ChatScreen(object): def __init__(self, screen_width, screen_height, bg_color): if not pygame.display.get_init(): turn_screen_on() pygame.init() self.standby_delay = 60 * 10 self.bg_color = bg_color self.lines = [] self.screen = pygame.display.set_mode((screen_width, screen_height)) self.rect = pygame.Rect(self.screen.get_rect()) self.rect.size = self.screen.get_size() self.size = self.screen.get_size() self.txt_layer = pygame.Surface(self.size) self.idle_timer = Timer(self.standby_delay, self.disable_display) self.changed = True self.lock = Lock() self.viewers = {} def set_line_height(self, lheight): self.line_height = lheight self.max_lines = int((self.size[HEIGHT] / self.line_height) - 1) def new_activity(self): with self.lock: if self.idle_timer.is_alive(): self.idle_timer.cancel() self.enable_display() self.idle_timer = Timer(self.standby_delay, self.disable_display) self.idle_timer.daemon = True self.idle_timer.start() self.changed = True def add_chatlines(self, lines): with self.lock: self.lines.extend(lines) self.lines = self.lines[-(self.max_lines):len(self.lines)] self.new_activity() def blit_quicktext(self, text, color=(255, 255, 255)): self.new_activity() font = pygame.font.Font("FreeSans.ttf", 72) surf = font.render(text, True, color) self.txt_layer.fill(self.bg_color) self.txt_layer.blit(surf, (self.rect.width / 2 - surf.get_rect().width / 2, self.rect.height / 2 - surf.get_rect().height / 2, 0, 0)) self.screen.blit(self.txt_layer, self.rect) pygame.display.update() def blit_lines(self, lines, surface): y_pos = self.size[HEIGHT] - (self.line_height * (len(lines) + 1)) viewerstring = '' for name in self.viewers: if self.viewers[name] > 0: viewerstring = viewerstring + ' {0} : {1}'.format(name, self.viewers[name]) if viewerstring: font = pygame.font.Font("FreeSans.ttf", 48) surf = font.render(viewerstring, True, (255, 255, 255)) y = self.size[HEIGHT] - self.line_height surface.blit(surf, (0, y, 0, 0)) for line in lines: x_pos = 0 for part in line: surface.blit(part, (x_pos, y_pos, 0, 0)) x_pos += part.get_width() y_pos += self.line_height def start(self): self.new_activity() self.start_rendering() def stop(self): turn_screen_on() if self.idle_timer.is_alive(): self.idle_timer.cancel() if self.rendering: self.rendering = False if self.render_thread.is_alive(): self.render_thread.join() pygame.quit() def start_rendering(self): self.rendering = True self.render_thread = Thread(target=self.render_loop) self.render_thread.daemon = True self.render_thread.start() def stop_rendering(self): self.rendering = False if self.render_thread.is_alive(): self.render_thread.join() def render_loop(self): while self.rendering: time.sleep(0.1) if self.changed: with self.lock: self.enable_display() self.txt_layer.fill(self.bg_color) self.blit_lines(self.lines, self.txt_layer) self.screen.blit(self.txt_layer, self.rect) pygame.display.update() self.changed = False def enable_display(self): if not pygame.display.get_init(): turn_screen_on() pygame.display.init() self.screen = pygame.display.set_mode((self.size[WIDTH], self.size[HEIGHT])) self.rect = pygame.Rect(self.screen.get_rect()) def disable_display(self): if pygame.display.get_init(): turn_screen_off() pygame.display.quit()
class trickleTimer(object): I = 0 # current interval size t = 0 # time within the current interval c = 0 # a counter def __init__(self, function, kwargs={}, Imin=0.1, Imax=16, k=2): """Trickle timer: - function: function to execute when the timer expires - kwargs: argument of the function - Imin: minimum interval size (default 100 ms) - Imax: maximum interval size, expressed in the number of doubling of the minimum interval size (default 16, that is 6553.6 seconds) - k: redundancy constant""" super(trickleTimer, self).__init__() self.Imin = Imin self.Imax = Imin * 2 ** Imax self.k = k # step 1 self.I = uniform(self.Imin, self.Imax) # step 2 self.c = 0 self.t = uniform(self.I / 2, self.I) # store the function, so that it can be rescheduled multiple times self.function = function self.kwargs = kwargs logger.debug("next trickle timer is set to run in %f seconds" % self.t) self.lock = RLock() self.thread = Timer(self.t, self.__run) self.thread.daemon = True def start(self): """Actually starts the timer""" with self.lock: if not self.thread.is_alive(): self.thread.start() def cancel(self): """Cancel the timer""" with self.lock: if self.thread.is_alive(): self.thread.cancel() def __run(self): """Run the function passed to the trickleTimer""" with self.lock: if self.can_transmit(): self.function(** self.kwargs) self.expired() def hear_consistent(self): """Receive a consistent message""" with self.lock: # step 3 logger.debug("Hearing a consistent message") self.c += 1 def can_transmit(self): """Check if the node can transmit its message (t has been reached)""" with self.lock: # step 4 return self.k == 0 or self.c < self.k def expired(self): """Trickle timer has expired""" with self.lock: # step 5 logger.debug("trickle timer has expired, increasing minimum interval size") self.I = self.I * 2 if self.I > self.Imax: logger.info("trickle timer has reached maximum interval size") self.I = self.Imax # this is not in the RFC, but in the trickle paper from NSDI'04 self.c = 0 # set the new timer self.t = uniform(self.I / 2, self.I) logging.debug("next trickle timer is set to run in %f seconds" % self.t) try: self.thread.cancel() # should never be needed except: pass self.thread = Timer(self.t, self.__run) self.thread.daemon = True self.thread.start() def hear_inconsistent(self): """Receive an inconsistent message (triggers timer reset)""" with self.lock: # step 6 logger.info("hearing an inconsistent message, reset trickle timer") if self.I != self.Imin: self.I = self.Imin self.c = 0 self.t = uniform(self.I / 2, self.I) self.cancel() self.thread = Timer(self.t, self.__run) self.thread.daemon = True self.thread.start() def __del__(self): self.cancel() super(trickleTimer, self).__del__()