def export(self, replace=True, name=None): """ Función que exporta las configuraciones a un directorio. :param replace: Reemplaza el archivo anterior :type replace: bool :param name: Nombre del archivo nuevo :rtype name: str :return: void :rtype: None """ try: if replace: name = self.filename f = open(name, "w") # Se escriben las configuraciones unarias for conf in self.config_single: f.write(str(conf) + "\n") # Se escriben las configuraciones complejas for key in self.configs.keys(): f.write(str(key) + CONFIG_SEPARATOR + self.configs[key] + "\n") # Se cierra el archivo f.close() if self.verbose: print CONFIG_SAVED.format(name) except: if self.verbose: errors.throw(errors.ERROR_CONFIGBADEXPORT)
def ssh_port(self): if not self.require([ "new_ssh_port" ]): return errors.throw(errors.BACKEND_INVALID_INPUT) self.force_cast_int("new_ssh_port") # change SSH port command self.do_execute( "sed -r \"s/^[ ]*[#]?[ ]*Port[ ]+[0-9]*[ ]*$/Port %d/g\" -i %s" % ( self.new_ssh_port, glob.config.get("paths", "sshd_config") ) ) # restart SSH command (exit_code,_,_) = self.do_execute( glob.config.get("paths", "initd") + "/sshd restart" ) # fail if exit_code != 0: return errors.throw(errors.SERVER_SSH_PORTCHANGE) return errors.throw(errors.ERR_SUCCESS)
def install(self): ret = super(xen_driver, self).install() if ret: return ret # get server object to work with srv = server.server(self.server) # see if it's already installed ret = self.__installed(srv) if ret == errors.DRIVER_ALREADY_INSTALLED: return ret # get distro distro = srv.get_remote_distro() if distro == "redhat": # get YUM package (exit_code,_,_) = srv.do_execute( "yum -y install xen xen-libs kernel-xen" ) if exit_code != 0: return errors.throw(errors.DRIVER_INSTALL_FAIL) return errors.throw(errors.ERR_SUCCESS) return errors.throw(errors.DRIVER_OS_NOT_SUPPORTED)
def translate(code, context = None): codes = { 0: errors.ERR_SUCCESS, 256: errors.XEN_DAEMON_NOT_RUNNING, } contexts = { 'create': { 1: errors.XEN_ERR_UNKNOWN, }, 'shutdown': { 1: errors.XEN_DOMAIN_DOESNT_EXIST, }, } # contextual exit codes try: return errors.throw(contexts[context][code]) except (IndexError, KeyError): pass # regular exit codes try: codes[code] except KeyError: return errors.throw(errors.XEN_ERR_UNKNOWN) return errors.throw(codes[code])
def passwd(self): ret = super(xen_core, self).passwd() if ret: return ret if self.os_type == "LINUX": # disk path disk_img_path = os.path.join(glob.config.get("xen", "root_domain_dir"), str(self.real_id), "sda1.img") # create loop directory mount point loop_dir = tempfile.mkdtemp(prefix="panenthe") self.do_execute('mkdir -p "%s"' % loop_dir) # mount loopback file self.mounts.append(loop_dir) (exit_code, _, _) = self.do_execute('mount -o loop "%s" "%s"' % (disk_img_path, loop_dir)) if exit_code != 0: return errors.throw(errors.XEN_DISK_READ) # run passwd in a chroot (exit_code, _, _) = self.do_execute( 'chroot "%s" /bin/bash -c "echo \\"%s:%s\\" | chpasswd"' % ( loop_dir, executer.escape(executer.escape(self.username)), executer.escape(executer.escape(self.password)), ) ) # clean up self.__quit_clean() return errors.throw(errors.ERR_SUCCESS)
def generate_keys(self): # LOL WTF AM I DOING. THAT -p SWITCH IS COMPLETELY USELESS HERE (exit_code, _, _) = execute("mkdir -p %s" % glob.config.get("paths", "user_ssh_config_dir")) if exit_code != 0: return errors.throw(errors.SERVER_MKDIR_ERROR) # remove any existing Panenthe keys try: os.unlink(glob.config.get("paths", "master_private_key")) except OSError: pass try: os.unlink(glob.config.get("paths", "master_public_key")) except OSError: pass # generate the trusted SSH key (exit_code, _, _) = execute('ssh-keygen -f %s -P ""' % glob.config.get("paths", "master_private_key")) # fail if exit_code != 0: return errors.throw(errors.SERVER_SSH_KEYGEN) # get trusted SSH key file = open(glob.config.get("paths", "master_public_key"), "r") public_key = file.read() file.close() # overwrite SSH key with identifier we can use to delete the key with file = open(glob.config.get("paths", "master_public_key"), "w") file.write(public_key[:-1] + "_panenthe\n") file.close() return errors.throw(errors.ERR_SUCCESS)
def set_hostname(self): ret = super(xen_core, self).set_hostname() if ret: return ret if self.hostname != self.new_hostname: # get relevant paths new_config_path = self.__get_config_path(self.new_hostname) old_config_path = self.__get_config_path() # try to overwrite hostname (exit_code, _, _) = self.do_execute( "sed -r" + ' "s/^hostname = \\".*\\"$/hostname = \\"%s\\"/g"' % (self.new_hostname) + ' -i "%s"' % old_config_path ) if exit_code != 0: return errors.throw(errors.XEN_MODIFY_CONFIG) # now move it to the new place (exit_code, _, _) = self.do_execute('mv "%s" "%s"' % (old_config_path, new_config_path)) if exit_code != 0: return errors.throw(errors.XEN_MOVE_CONFIG) return errors.throw(errors.ERR_SUCCESS)
def __init__(self, language, **kwargs): """ Función constructora :param language: Idioma a cargar (path) :param kwargs: Parámetros adicionales :return: void """ language = str(language).upper() if language + langconfig.getValue(0) in langavaiable.getParameters(): try: file = open(_LANG_DIRLANGS + language + langconfig.getValue(0)) # @ReservedAssignment except: errors.throw(errors.ERROR_NOLANGFILE, language) self.lang = {} # noinspection PyUnboundLocalVariable for line in file: line = line.strip().replace("\ufeff", "").split(_SPLITTER) # Elimino caracteres que no sean utf-8 if '\xef\xbb\xbf' in line[0]: line[0] = line[0][3:] if line[0] == "": line[0] = "10" self.lang[int(line[0].replace("\ufeff", ""))] = line[1].replace( _SPACE, " ") file.close() if kwargs.get("verbose"): print(LANG_LOADED.format(language)) self.langname = language else: errors.throw(errors.ERROR_NOLANGDEFINED)
def add_ip(self): if not self.require(["real_id", "ip", "netmask", "gateway"]): return errors.throw(errors.BACKEND_INVALID_INPUT) # incoming traffic (exit_code,_,_) = iptables.add_rule( "PANENTHE_BW", "-d %s" % self.ip, self.do_execute ) if exit_code != 0: return errors.throw(errors.SERVER_IPTABLES) # outgoing traffic (exit_code,_,_) = iptables.add_rule( "PANENTHE_BW", "-s %s" % self.ip, self.do_execute ) if exit_code != 0: return errors.throw(errors.SERVER_IPTABLES) # save rules srv = self.get_server() error = iptables.save(srv.do_execute, srv.get_remote_distro()) if error != errors.ERR_SUCCESS: return error
def __init__(self, language, **kwargs): """ Función constructora :param language: Idioma a cargar (path) :param kwargs: Parámetros adicionales :return: void """ language = str(language).upper() if language + langconfig.getValue(0) in langavaiable.getParameters(): try: file = open(_LANG_DIRLANGS + language + langconfig.getValue(0), "r") # @ReservedAssignment except: errors.throw(errors.ERROR_NOLANGFILE, language) self.lang = {} # noinspection PyUnboundLocalVariable for line in file: line = line.strip().replace("\ufeff", "").split(_SPLITTER) if "\xef\xbb\xbf" in line[0]: # elimino caracteres que no sean utf-8 line[0] = line[0][3:] if line[0] == "": line[0] = "10" self.lang[int(line[0].replace("\ufeff", ""))] = line[1].replace(_SPACE, " ") file.close() if kwargs.get("verbose"): print LANG_LOADED.format(language) self.langname = language else: errors.throw(errors.ERROR_NOLANGDEFINED)
def __get_xentop_info(self): try: self.xentop_info return errors.throw(errors.ERR_SUCCESS) except AttributeError: pass (exit_code, stdout, _) = self.do_execute("xentop -b -i 1") if exit_code != 0: return xen_exit_codes.translate(exit_code) # get this VPS' information line = -1 split_info = None for i in xrange(4, len(stdout)): # domain info starts on line 5 info = re.sub("[ ]+", " ", stdout[i].strip()) split_info = info.split(" ") if split_info[0] == str(self.real_id): line = i break # cache it locally if line == -1: self.xentop_info = -1 else: self.xentop_info = split_info return errors.throw(errors.ERR_SUCCESS)
def stat_load(self): # execute uptime (exit_code,stdout,_) = self.do_execute( glob.config.get("paths", "uptime") ) # error with the uptime command if exit_code != 0: return errors.throw(errors.SERVER_UPTIME) # gather load averages stdout_arr = stdout[0].split(" ") load_average_1 = stdout_arr[-3].strip(",") load_average_5 = stdout_arr[-2].strip(",") load_average_15 = stdout_arr[-1].strip(",") # start PHP exits php_exit_first = False # update stats db (php_exit_code,_,_) = php.db_update( "server_stats", "update_attribute", str(self.get_server_id()), "load_average_1", load_average_1 ) # just throw, DO NOT RETURN if php_exit_code != 0: php_exit_codes.translate(php_exit_code) if not php_exit_first: php_exit_first = php_exit_code # update stats db (php_exit_code,_,_) = php.db_update( "server_stats", "update_attribute", str(self.get_server_id()), "load_average_5", load_average_5 ) # just throw, DO NOT RETURN if php_exit_code != 0: php_exit_codes.translate(php_exit_code) if not php_exit_first: php_exit_first = php_exit_code # update stats db (php_exit_code,_,_) = php.db_update( "server_stats", "update_attribute", str(self.get_server_id()), "load_average_15", load_average_15 ) # return code if php_exit_first: return php_exit_codes.translate(php_exit_first) else: return errors.throw(errors.ERR_SUCCESS)
def file_sync(self, sync_file): # see if file exists (exit_code,_,_) = self.do_execute("test -e %s" % sync_file) # copy flag copy = True # OST exists, check MD5 if exit_code == 0: # local md5 (exit_code,stdout,_) = execute("md5sum %s" % sync_file) # no file found locally if stdout == []: return errors.throw(errors.SERVER_FILE_NOT_FOUND) local_md5 = stdout[0].strip().split(" ")[0] if exit_code == 0: # remote MD5 (exit_code,stdout,_) = self.do_execute( "md5sum %s" % sync_file ) if exit_code == 0: try: remote_md5 = stdout[0].strip().split(" ")[0] remote_success = True except IndexError: remote_success = False else: remote_success = False # compare if remote_success and local_md5 == remote_md5: copy = False # remove existing template else: self.do_execute("rm -f %s" % sync_file) # copy over OST if copy: self.do_execute("mkdir -p \"%s\"" % os.path.dirname(sync_file)) execute( "scp -i %s -P %d %s root@%s:%s" % ( glob.config.get("paths", "master_private_key"), self.remote_server['port'], sync_file, executer.escape(self.remote_server['ip']), sync_file ) ) return errors.throw(errors.ERR_SUCCESS)
def shutdown(self): (exit_code,_,_) = self.do_execute( "%s -h now" % glob.config.get("paths", "shutdown") ) # fail if exit_code != 0: return errors.throw(errors.SERVER_SHUTDOWN) return errors.throw(errors.ERR_SUCCESS)
def __init__(self, dict): super(vps, self).__init__(dict) # verify all fields are present if not self.require([ "vps_id", "hostname", "driver", "server", "master" ]): return errors.throw(errors.BACKEND_INVALID_INPUT) # force casting of vps fields self.force_cast_int("vps_id") # verify all master fields are present if not self.require_dict(self.master, [ "server_id", "parent_server_id", "hostname", "ip", "port" ]): return errors.throw(errors.BACKEND_INVALID_INPUT) # force casting of master fields self.force_cast_int_dict("master", [ "server_id", "parent_server_id", "port" ]) # verify all server fields are present if not self.require_dict(self.server, [ "server_id", "parent_server_id", "hostname", "ip", "port" ]): return errors.throw(errors.BACKEND_INVALID_INPUT) # force casting of server fields self.force_cast_int_dict("server", [ "server_id", "parent_server_id", "port" ]) # add drivers path to system path for import sys.path.append(glob.getfile("drivers", self.driver)) # start out with undefined executer self.executer = None
def status(self): ret = super(xen_core, self).status() if ret: return ret self.__get_xentop_info() # if we didn't find it, it's not started if self.xentop_info == -1: return errors.throw(errors.VPS_STATUS_STOPPED) return errors.throw(errors.VPS_STATUS_RUNNING)
def modify(self): if not self.require([ "old_data", "real_id", "disk_space", "backup_space", "swap_space", "g_mem", "b_mem", "cpu_pct", "cpu_num", "in_bw", "out_bw" ]): return errors.throw(errors.BACKEND_INVALID_INPUT) self.force_cast_int([ "disk_space", "backup_space", "swap_space", "g_mem", "b_mem", "cpu_pct", "cpu_num", "in_bw", "out_bw" ]) if not self.require_dict(self.old_data, [ "disk_space", "backup_space", "swap_space", "g_mem", "b_mem", "cpu_pct", "cpu_num", "in_bw", "out_bw" ]): return errors.throw(errors.BACKEND_INVALID_INPUT) self.force_cast_int_dict("old_data", [ "disk_space", "backup_space", "swap_space", "g_mem", "b_mem", "cpu_pct", "cpu_num", "in_bw", "out_bw" ])
def __installed(self, srv): # check to make sure it's not already a Xen kernel (exit_code,stdout,_) = srv.do_execute("uname -r") if exit_code != 0: return errors.throw(errors.DRIVER_INSTALL_FAIL) # search for xen on kernel name search = stdout[0].find("xen") # already installed if search != -1: return errors.throw(errors.DRIVER_ALREADY_INSTALLED)
def translate(code): codes = { 0: errors.ERR_SUCCESS, 1: errors.PHP_DATABASE_FAIL, 127: errors.PHP_FILE_NOT_FOUND, } try: codes[code] except KeyError: return errors.throw(errors.PHP_ERR_UNKNOWN) return errors.throw(codes[code])
def __init__(self, directory, conffile, **kwargs): """ Función constructora de la clase. Keywords: - verbose (bool) = Indica si se imprime el estado de ejecución o no en consola :param directory: Ubicación del archivo de configuraciones :type directory: str :param conffile: Nombre del archivo de configuraciones :type conffile: str :param kwargs: Parámetros adicionales :type kwargs: list :return: void """ # Se carga el archivo de configuraciones filename = directory + conffile try: # noinspection PyShadowingBuiltins file = open(filename.replace("\\", "/"), "r") # @ReservedAssignment except: errors.throw(errors.ERROR_NOCONFIGFILE, filename) # Variables self.config_single = [] self.configs = {} self.filename = filename self.filename_title = conffile self.totalconfigs = 0 # Se cargan las configuraciones for configline in file: if configline[0] != CONFIG_COMMENT and configline != "\n": config = string2list(configline, CONFIG_SEPARATOR) if len(config) == 1: self.config_single.append(config[0]) elif len(config) == 2: self.totalconfigs += 1 self.configs[config[0]] = config[1] else: errors.throw(errors.ERROR_BADCONFIG, configline, filename) if kwarg_is_true_param(kwargs, "verbose"): self.verbose = True if not (self.totalconfigs + len(self.config_single)): errors.warning(errors.WARNING_NOCONFIGFOUND, filename) else: print CONFIG_LOAD.format(filename) else: self.verbose = False file.close()
def stop(self): ret = super(ovz_driver, self).stop() if ret: return ret (exit_code,_,_) = execute_drv(self, "%s stop" % os.path.join( glob.config.get("paths", "initd"), "vz" ) ) if exit_code != 0: return errors.throw(errors.DRIVER_STOP_FAIL) return errors.throw(errors.ERR_SUCCESS)
def restart(self): ret = super(xen_driver, self).restart() if ret: return ret (exit_code,_,_) = execute_drv(self, "%s restart" % os.path.join( glob.config.get("paths", "initd"), "xend" ) ) if exit_code != 0: return errors.throw(errors.DRIVER_RESTART_FAIL) return errors.throw(errors.ERR_SUCCESS)
def event_log(self, cls, cmd, control, error_code): # entity has a driver try: control.entity.driver # read driver config for messages q_messages.read_driver(control.entity.driver) # add drivers path to system path for import sys.path.append(glob.getfile("drivers", control.entity.driver)) # import, and make sure it exists try: exec("from %s_q_after_exec import %s_q_after_exec" % ( control.entity.driver, control.entity.driver )) exec("tmp = %s_q_after_exec()" % control.entity.driver) exec("after_ret = tmp.execute(cls, cmd, control.entity)") except ImportError: after_ret = errors.throw(DRIVER_NO_AFTER_EXEC) # entity has no driver except AttributeError: # queue_mode afterwards execution from q_after_exec import q_after_exec tmp = q_after_exec() after_ret = tmp.execute(cmd, cls, control.entity) # get event message event_msg = q_messages.get(cls, cmd, control.entity, error_code) # insert event if there is a message if event_msg != None: php.db_update("events", "insert", event_msg, error_code[0])
def rebuild(self): if not self.require([ "real_id", "disk_space", "backup_space", "swap_space", "g_mem", "b_mem", "cpu_pct", "cpu_num", "in_bw", "out_bw", "ost" ]): return errors.throw(errors.BACKEND_INVALID_INPUT) self.force_cast_int([ "disk_space", "backup_space", "swap_space", "g_mem", "b_mem", "cpu_pct", "cpu_num", "in_bw", "out_bw" ])
def remove_all_ips(self): if not self.require("real_id"): return errors.throw(errors.BACKEND_INVALID_INPUT) # vps IP addresses ac = api.api_call("vm_ips", { 'vps_id': self.vps_id }) ret = ac.execute() if ret != errors.ERR_SUCCESS: return ret # remove IPs from iptables try: ips = ac.output()[0]['ip'] # loop through IPs and remove for ip in ips: iptables.delete_rule( "PANENTHE_BW", "-d %s" % ip, self.do_execute ) iptables.delete_rule( "PANENTHE_BW", "-s %s" % ip, self.do_execute ) except (IndexError, KeyError): pass # save rules srv = self.get_server() error = iptables.save(srv.do_execute, srv.get_remote_distro()) if error != errors.ERR_SUCCESS: return error
def next_id(self): ret = super(ovz_core, self).next_id() if ret: return ret # real_id is fine try: self.real_id # need new real_id except AttributeError: ret = ovz_core.get_new_real_id(self) # fail if not type(ret) == int: return errors.throw(errors.OVZ_GENERATE_REAL_ID) # success self.real_id = ret # update DB (php_exit_code,_,_) = php.db_update( "vps", "update_real_id", str(self.vps_id), str(self.real_id) ) return php_exit_codes.translate(php_exit_code)
def __init__(self, dict): super(server, self).__init__(dict) # NOTE: if you change the server requirements here, make sure to change # them in driver.py as well # verify all fields are present if not self.require([ "server_id", "parent_server_id", "hostname", "ip", "port" ]): return errors.throw(errors.BACKEND_INVALID_INPUT) # force casting of vps fields self.force_cast_int([ "server_id", "parent_server_id", "port" ]) # no executer until a function makes one self.executer = None
def stat_uptime(self): # execute uptime (exit_code,stdout,_) = self.do_execute( glob.config.get("paths", "uptime") ) # error with the uptime command if exit_code != 0: return errors.throw(errors.SERVER_UPTIME) # get uptime stdout_arr = stdout[0].split(",") uptime = stdout_arr[0][stdout_arr[0].index("up")+2:].strip() if uptime[-4:] == "days": uptime += " " + stdout_arr[1].strip() # update stats db (php_exit_code,_,_) = php.db_update( "server_stats", "update_attribute", str(self.get_server_id()), "uptime", uptime ) # return code return php_exit_codes.translate(php_exit_code)
def stat_images(self): # get image listing (exit_code,images,_) = self.do_execute("ls -1 /boot") if exit_code != 0: return errors.throw(errors.SERVER_LIST_IMAGES) new_images = [] for i in xrange(0, len(images)): # only get vmlinu.* stuff if not re.match("vmlinu", images[i]): continue # put xenU kernel to be first kernel elif re.search("xenU", images[i]): new_images.insert(0, images[i]) # otherwise tack it onto the end else: new_images.append(images[i]) # newline delimited nl_images = "\n".join(new_images) # update db (php_exit_code,_,_) = php.db_update( "server_stats", "update_attribute", str(self.get_server_id()), "kernel_images", nl_images )
def __init__(self, cmd, dict): super(vpsctl, self).__init__(cmd, dict) if not self.require([ "driver" ]): return errors.throw(errors.BACKEND_INVALID_INPUT)
def activate(self): ret = super(xen_driver, self).activate() if ret: return ret # get server object to work with srv = server.server(self.server) # get the kernel number from the grub config (_,stdout,_) = srv.do_execute( "/usr/bin/env grep -E \"^[ ]*title\" %s | " % glob.config.get("paths", "grub_config") + "/usr/bin/env grep -B 1000 xen | /usr/bin/env wc -l" ) grub_number = int(stdout[0])-1 # set the xen to boot as the default kernel srv.do_execute( "/usr/bin/env sed -r \"s/^[ ]*default[ ]*=.*$/default=%s/g\" " % grub_number + "-i %s" % glob.config.get("paths", "grub_config") ) # reboot if necessary if self.reboot: # backgrounded, just in case it matters srv.do_execute("%s -r now &" % glob.config.get("paths", "shutdown")) return errors.throw(errors.ERR_SUCCESS)
def getValue(self, param): """ Retorna el valor del parametro param :param param: Parámetro :return: valor """ if str(param).isdigit(): param = int(param) if 0 <= param < len(self.config_single): return self.config_single[param] else: errors.throw(errors.ERROR_BADINDEXCONFIG, str(param)) else: if param in self.getParameters(): return self.configs[param] else: errors.warning(errors.ERROR_CONFIGNOTEXISTENT, param)
def __init__(self, filename, **kwargs): """ Función constructora :param filename: Nombre del archivo :param kwargs: Parámetros adicionales :return: void """ # Se carga el archivo de configuraciones try: file = open(filename.replace('\\', '/')) # @ReservedAssignment except: errors.throw(errors.ERROR_NOCONFIGFILE, filename) # Variables self.config_single = [] self.configs = {} self.filename = filename self.totalconfigs = 0 # Se cargan las configuraciones # noinspection PyUnboundLocalVariable for configline in file: if configline[0] != CONFIG_COMMENT and configline != "\n": config = string2list(configline, CONFIG_SEPARATOR) if len(config) == 1: self.config_single.append(config[0]) elif len(config) == 2: self.totalconfigs += 1 self.configs[config[0]] = config[1] else: errors.throw(errors.ERROR_BADCONFIG, configline, filename) if kwargs.get("verbose"): self.verbose = True if not (self.totalconfigs + len(self.config_single)): errors.warning(errors.WARNING_NOCONFIGFOUND, filename) else: print(CONFIG_LOAD.format(filename)) else: self.verbose = False file.close()
def export(self, replace=True, name=None): """ Función que exporta las configuraciones a un directorio :param replace: Reemplaza el archivo anterior :param name: Nombre del archivo nuevo :return: void """ try: if replace: name = self.filename f = open(name, "w") # Se escriben las configuraciones unarias for conf in self.config_single: f.write(str(conf) + "\n") # Se escriben las configuraciones complejas for key in self.configs.keys(): f.write(str(key) + CONFIG_SEPARATOR + self.configs[key] + "\n") # Se cierra el archivo f.close() if self.verbose: print(CONFIG_SAVED.format(name)) except: if self.verbose: errors.throw(errors.ERROR_CONFIGBADEXPORT)
from path import * # @UnusedWildImport # Importación de librerías de sistema # noinspection PyBroadException try: from datetime import date from random import choice from urllib import urlencode, urlopen from urllib2 import urlopen, Request import ctypes import os import signal import string import time except Exception: errors.throw(errors.ERROR_IMPORTSYSTEMERROR) # Importación de librerías externas # noinspection PyBroadException try: # noinspection PyUnresolvedReferences import WConio # @UnresolvedImport except: if os.name == "nt": errors.warning(errors.ERROR_IMPORTWCONIO) # Constantes _CMD_COLORS = { "blue": 0x10, "gray": 0x80, "green": 0x20,
__binconfig = Configloader(bindir._DIR_CONFIG + "bin.ini") # noinspection PyUnresolvedReferences sys.setdefaultencoding(__binconfig.getValue("SET_DEFAULT_ENCODING")) if __binconfig.isTrue("DONT_WRITE_BYTECODE"): # noinspection PyCompatibility reload(sys) sys.dont_write_bytecode = True # Importación de librerías externas # noinspection PyCompatibility try: # noinspection PyUnresolvedReferences import mechanize # @UnresolvedImport @NoMove except Exception, e: print(str(e)) errors.throw(errors.ERROR_IMPORTERRORMECHANIZE) # noinspection PyCompatibility,PyBroadException try: # noinspection PyUnresolvedReferences from pil import Image # @UnresolvedImport except Exception, e: errors.throw(errors.ERROR_IMPORTERRORPIL) # Importación de librerías internas # noinspection PyCompatibility try: from pygame import * import pygame import pygame.gfxdraw except Exception, e: print(str(e))