def get_issued_orders(domain_filter=None): logger = loggers.get_logger(__name__) check_credential() filters = '?filters[status]=issued&filters[product_type]=ssl_certificate' r = Request().get('/order/certificate{0}'.format(filters)) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format(r.get_message())) sys.exit() order_list = r.data['orders'] if 'orders' in r.data else [] logger.debug("Collected order list with {0} orders".format(len(order_list))) orders = [] for order in order_list: if domain_filter and order['product']['type'] != 'client_certificate': if domain_filter in order['certificate']['dns_names']: orders.append(order) else: # Check for wildcard matches for dns_name in order['certificate']['dns_names']: # For dns_name *.example.com, the domain_filter ends with .example.com or equals example.com if (dns_name[:2] == '*.') and (dns_name[1:] == domain_filter[1-len(dns_name):] or dns_name[2:] == domain_filter): orders.append(order) break logger.debug("Returning {0} orders after filtering".format(len(orders))) return orders
def download_certificate(order): logger = loggers.get_logger(__name__) check_credential() logger.debug("Downloading certificate") # TODO this distinction shouldn't exist here if 'certificate' in order and 'id' in order['certificate'] and order['certificate']['id']: # for cert central accounts r = Request(raw_file=True).get('/certificate/{0}/download/format/pem_all'.format(order['certificate']['id'])) else: # for mpki/retail accounts params = {"format_type": "pem_all"} if 'sub_id' in order and order['sub_id']: params["sub_id"] = order['sub_id'] r = Request(raw_file=True).get('/certificate/download/order/{0}'.format(order['id']), params) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format(r.get_message())) sys.exit() logger.debug("Downloaded certificate for order #{0}".format(order['id'])) certs = r.data.split("-----BEGIN") # 0 - empty, 1 - cert, 2 - intermediate, 3 - root... do we need root? return { "certificate": "-----BEGIN{0}".format(certs[1]), "intermediate": "-----BEGIN{0}".format(certs[2]), "root": "-----BEGIN{0}".format(certs[3]), }
def set_permission(file_path, user_name, mode=755): logger = loggers.get_logger(__name__) # change the owners of the ssl files logger.info("Making file {0} readable by {1} with mode {2}".format(file_path, user_name, mode)) os.system("chown root:{0} {1}".format(user_name, file_path)) # change the permission of the ssl files, only the root and apache users should have read permissions os.system("chmod {0} {1}".format(mode, file_path))
def train(args): args, model, iters, vocab, ckpt_available = get_model_ckpt(args) if ckpt_available: print("loaded checkpoint {}".format(args.ckpt_name)) loss_fn = get_loss(args, vocab) optimizer = get_optimizer(args, model) trainer = get_trainer(args, model, loss_fn, optimizer) metrics = get_metrics(args, vocab) evaluator = get_evaluator(args, model, loss_fn, metrics) logger = get_logger(args) @trainer.on(Events.STARTED) def on_training_started(engine): print("Begin Training") @trainer.on(Events.ITERATION_COMPLETED) def log_iter_results(engine): log_results(logger, 'train/iter', engine.state, engine.state.iteration) @trainer.on(Events.EPOCH_COMPLETED) def evaluate_epoch(engine): log_results(logger, 'train/epoch', engine.state, engine.state.epoch) state = evaluate_once(evaluator, iterator=iters['val']) log_results(logger, 'valid/epoch', state, engine.state.epoch) save_ckpt(args, engine.state.epoch, engine.state.metrics['loss'], model, vocab) trainer.run(iters['train'], max_epochs=args.max_epochs)
def get_issued_orders(domain_filter=None): logger = loggers.get_logger(__name__) check_credential() filters = '?filters[status]=issued&filters[product_type]=ssl_certificate' r = Request().get('/order/certificate{0}'.format(filters)) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format( r.get_message())) sys.exit() order_list = r.data['orders'] if 'orders' in r.data else [] logger.debug("Collected order list with {0} orders".format( len(order_list))) orders = [] for order in order_list: if domain_filter and order['product']['type'] != 'client_certificate': if domain_filter in order['certificate']['dns_names']: orders.append(order) else: # Check for wildcard matches for dns_name in order['certificate'][ 'dns_names']: # For dns_name *.example.com, the domain_filter ends with .example.com or equals example.com if (dns_name[:2] == '*.') and ( dns_name[1:] == domain_filter[1 - len(dns_name):] or dns_name[2:] == domain_filter): orders.append(order) break logger.debug("Returning {0} orders after filtering".format(len(orders))) return orders
def request_login(): logger = loggers.get_logger(__name__) # do you have a DigiCert api key? <y> logger.info("Please login to continue.") username = raw_input("DigiCert Username: "******"DigiCert Password: "******"Authentication failed. Unable to continue.") sys.exit() return r.data["api_key"]
def create_duplicate(order, csr_file): logger = loggers.get_logger(__name__) check_credential() csr_text = None with open(csr_file, "r") as f: csr_text = f.read() # TODO consider changing common name to vhost if we need to or can cert_data = { "certificate": { "common_name": order['certificate']['common_name'], "csr": csr_text, "signature_hash": order['certificate']['signature_hash'], "server_platform": { "id": 2 }, "dns_names": order['certificate']['dns_names'] } } logger.debug( "Submitting request for duplicate on order #{0} with data {1}".format( order['id'], json.dumps(cert_data))) r = Request().post('/order/certificate/{0}/duplicate'.format(order['id']), cert_data) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format( r.get_message())) sys.exit() logger.debug("Duplicate request succeeded with response {0}".format( json.dumps(r.data))) return r.data
def download_certificate(order): logger = loggers.get_logger(__name__) check_credential() logger.debug("Downloading certificate") # TODO this distinction shouldn't exist here if 'certificate' in order and 'id' in order['certificate'] and order[ 'certificate']['id']: # for cert central accounts r = Request(raw_file=True).get( '/certificate/{0}/download/format/pem_all'.format( order['certificate']['id'])) else: # for mpki/retail accounts params = {"format_type": "pem_all"} if 'sub_id' in order and order['sub_id']: params["sub_id"] = order['sub_id'] r = Request(raw_file=True).get( '/certificate/download/order/{0}'.format(order['id']), params) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format( r.get_message())) sys.exit() logger.debug("Downloaded certificate for order #{0}".format(order['id'])) certs = r.data.split( "-----BEGIN" ) # 0 - empty, 1 - cert, 2 - intermediate, 3 - root... do we need root? return { "certificate": "-----BEGIN{0}".format(certs[1]), "intermediate": "-----BEGIN{0}".format(certs[2]), "root": "-----BEGIN{0}".format(certs[3]), }
def determine_platform(): logger = loggers.get_logger(__name__) distro_name = platform.linux_distribution() # returns a tuple ('', '', '') (distroName, version, code name) logger.debug("Found platform: {0}".format(" : ".join(distro_name))) if "centos" in distro_name[0].lower(): return centos_platform.CentosPlatform() else: return ubuntu_platform.UbuntuPlatform()
def __init__(self, api_key=None, raw_file=False, **kwargs): if api_key: self._api_key = api_key self._headers['X-DC-DEVKEY'] = self._api_key if not api_key and config.API_KEY: self._api_key = config.API_KEY self._headers['X-DC-DEVKEY'] = self._api_key self._log = loggers.get_logger(__name__) self._raw_file = raw_file
def get_order(order_id): logger = loggers.get_logger(__name__) check_credential() r = Request().get('/order/certificate/{0}'.format(order_id)) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format(r.get_message())) sys.exit() logger.debug("Returning order #{0}".format(r.data['id'])) return r.data
def get_order(order_id): logger = loggers.get_logger(__name__) check_credential() r = Request().get('/order/certificate/{0}'.format(order_id)) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format( r.get_message())) sys.exit() logger.debug("Returning order #{0}".format(r.data['id'])) return r.data
def get_duplicates(order_id): logger = loggers.get_logger(__name__) check_credential() logger.debug("Getting list of duplicates from API") r = Request().get('/order/certificate/{0}/duplicate'.format(order_id)) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format(r.get_message())) sys.exit() logger.debug("Collected {0} duplicates for order_id {1}".format(len(r.data), order_id)) return r.data
def validate_ssl_success(dns_name): logger = loggers.get_logger(__name__) # For simply checking that the site is available HTTPSConnection is good enough logger.info("Verifying {0} is available over HTTPS...".format(dns_name)) try: conn = HTTPSConnection(dns_name, timeout=10) conn.request('GET', '/') response = conn.getresponse() if str(response.status)[0] == '2': logger.info("{0} is reachable over HTTPS".format(dns_name)) return True error = "Application error occurred with status: {0}".format(response.status) except Exception as e: error = str(e) logger.info("There was a problem checking SSL site availability, your site may not be secure: {0}".format(error)) return False
def approve_request(request_id): logger = loggers.get_logger(__name__) check_credential() data = {"status": "approved", "processor_comment": "Automatically approved by Express Install"} logger.debug("Submitting approval to the API") r = Request().put('/request/{0}/status'.format(request_id), data) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format(r.get_message())) sys.exit() logger.debug("Approval succeeded with response [{0}] {1}".format(r.status_code, json.dumps(r.data) if r.data else "No response")) return r.data
def get_dns_names_from_cert(cert_path): logger = loggers.get_logger(__name__) if not cert_path or not os.path.isfile(cert_path): logger.info("Couldn't find valid certificate file: {0}".format(cert_path if cert_path else "No certificate provided")) return [] dns_names = [] sans = "" cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, open(cert_path, 'r').read()) for idx in range(cert.get_extension_count()): ext = cert.get_extension(idx) if ext.get_short_name() == 'subjectAltName': sans = str(ext) # DNS:nocsr.com break dns_names = [x.split(':')[1] for x in sans.split(',') if x] return dns_names
def upload_csr(order_id, csr_file): logger = loggers.get_logger(__name__) check_credential() csr_text = None logger.debug("Reading CSR from file at {0}".format(csr_file)) with open(csr_file, "r") as f: csr_text = f.read() r = Request().post('/order/certificate/{0}/csr'.format(order_id), {'csr': csr_text}) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format(r.get_message())) sys.exit() logger.info("Updated CSR on order #{0}".format(order_id))
def get_duplicates(order_id): logger = loggers.get_logger(__name__) check_credential() logger.debug("Getting list of duplicates from API") r = Request().get('/order/certificate/{0}/duplicate'.format(order_id)) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format( r.get_message())) sys.exit() logger.debug("Collected {0} duplicates for order_id {1}".format( len(r.data), order_id)) return r.data
def upload_csr(order_id, csr_file): logger = loggers.get_logger(__name__) check_credential() csr_text = None logger.debug("Reading CSR from file at {0}".format(csr_file)) with open(csr_file, "r") as f: csr_text = f.read() r = Request().post('/order/certificate/{0}/csr'.format(order_id), {'csr': csr_text}) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format( r.get_message())) sys.exit() logger.info("Updated CSR on order #{0}".format(order_id))
def create_duplicate(order, csr_file): logger = loggers.get_logger(__name__) check_credential() csr_text = None with open(csr_file, "r") as f: csr_text = f.read() # TODO consider changing common name to vhost if we need to or can cert_data = {"certificate": {"common_name": order['certificate']['common_name'], "csr": csr_text, "signature_hash": order['certificate']['signature_hash'], "server_platform": {"id": 2}, "dns_names": order['certificate']['dns_names']}} logger.debug("Submitting request for duplicate on order #{0} with data {1}".format(order['id'], json.dumps(cert_data))) r = Request().post('/order/certificate/{0}/duplicate'.format(order['id']), cert_data) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format(r.get_message())) sys.exit() logger.debug("Duplicate request succeeded with response {0}".format(json.dumps(r.data))) return r.data
def find_user_config(): """ see if there is a custom configuration file in the user's home folder and update the config vars appropriately """ logger = loggers.get_logger(__name__) username = os.environ["SUDO_USER"] if "SUDO_USER" in os.environ and os.environ["SUDO_USER"] else os.environ["USER"] home = os.path.expanduser("~{0}/".format(username)) logger.info("Looking for user config in {0}".format(home)) if os.path.isfile("{0}/.digicert_express".format(home)): logger.info("Found user config") cfg = open("{0}/.digicert_express".format(home), "r").read() usercfg = json.loads(cfg) if 'SERVICES_URL' in usercfg and usercfg['SERVICES_URL']: config.SERVICES_URL = usercfg['SERVICES_URL'] if 'API_KEY' in usercfg and usercfg['API_KEY']: config.API_KEY = usercfg['API_KEY'] if 'FILE_STORE' in usercfg and usercfg['FILE_STORE']: config.FILE_STORE = usercfg['FILE_STORE'] if 'SEARCH_PATHS' in usercfg and usercfg['SEARCH_PATHS']: config.SEARCH_PATHS = usercfg['SEARCH_PATHS'] if 'LOG_FILE' in usercfg and usercfg['LOG_FILE']: config.LOG_FILE = usercfg['LOG_FILE']
def approve_request(request_id): logger = loggers.get_logger(__name__) check_credential() data = { "status": "approved", "processor_comment": "Automatically approved by Express Install" } logger.debug("Submitting approval to the API") r = Request().put('/request/{0}/status'.format(request_id), data) if r.has_error: # This is an unrecoverable error. We can't see the API for some reason if r.is_response_error(): logger.error('Server request failed. Unable to access API.') sys.exit() else: logger.error("Server returned an error condition: {0}".format( r.get_message())) sys.exit() logger.debug("Approval succeeded with response [{0}] {1}".format( r.status_code, json.dumps(r.data) if r.data else "No response")) return r.data
def create_csr(dns_name, order=None): """ Uses this data to create a CSR via OpenSSL :param dns_name: :param order: :return: """ logger = loggers.get_logger(__name__) logger.info("Creating CSR file for {0}...".format(dns_name)) if not os.path.isdir("{0}/{1}".format(config.FILE_STORE, normalize_common_name_file(dns_name))): os.makedirs("{0}/{1}".format(config.FILE_STORE, normalize_common_name_file(dns_name)), 0755) key_file_name = "{0}/{1}/{1}.key".format(config.FILE_STORE, normalize_common_name_file(dns_name)) csr_file_name = "{0}/{1}/{1}.csr".format(config.FILE_STORE, normalize_common_name_file(dns_name)) subj = "/C=/ST=/L=/O=/CN={0}".format(dns_name) if order and 'organization' in order: org = order['organization'] country = org['country'] if 'country' in org else "" state = org['state'].replace(",", "") if 'state' in org else "" city = org['city'].replace(",", "") if 'city' in org else "" name = org['name'].replace(",", "") if 'name' in org else "" subj = "/C={0}/ST={1}/L={2}/O={3}/CN={4}".format(country, state, city, name, dns_name) csr_cmd = 'openssl req -new -newkey rsa:2048 -nodes -out {0} -keyout {1} -subj "{2}" 2>/dev/null'.format(csr_file_name, key_file_name, subj) # run the command os.system(csr_cmd) # verify the existence of the key and csr files if not os.path.exists(key_file_name) or not os.path.exists(csr_file_name): raise Exception("ERROR: An error occurred while attempting to create your CSR file. Please try running {0} " "manually and re-run this application with the CSR file location " "as part of the arguments.".format(csr_cmd)) logger.info("Created private key file {0}...".format(key_file_name)) logger.info("Created CSR file {0}...".format(csr_file_name)) print "" return key_file_name, csr_file_name
def validate_private_key(private_key_path, cert_path): logger = loggers.get_logger(__name__) try: private_key_obj = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, open(private_key_path, 'r').read()) except OpenSSL.crypto.Error: logger.info("Private key path was invalid") return False try: cert_obj = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, open(cert_path, 'r').read()) except OpenSSL.crypto.Error: logger.info("Certificate path was invalid") return False context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD) context.use_privatekey(private_key_obj) context.use_certificate(cert_obj) try: context.check_privatekey() return True except OpenSSL.SSL.Error as e: logger.debug("Private key and certificate did not match: {0}".format(str(e))) logger.info("\033[1mThe private key provided did not match the certificate.\033[0m") return False
def _init_logger(self): self.logger = loggers.get_logger(self)
# Third-party imports from datetime import datetime # Local imports from app.admin.forms import DepartmentForm, EmployeeEditForm, department_query, get_pk from app.auth.forms import RegistrationForm, LoginForm from app.models import Department from loggers import get_logger from app.util import TestBase logger = get_logger(__name__) class TestAuthForms(TestBase): def test_validate_success_register_form(self): """Test whether registration works correctly. Returns: None """ date = datetime.strptime('1996-01-01', '%Y-%m-%d').date() form = RegistrationForm( email='*****@*****.**', username='******', first_name='test', last_name='test', date_of_birth=date, password='******',
def _init_logger(self): logger_config = self.test_config.logger_config self.logger = loggers.get_logger(self, logger_config)
import logging import os import signal from logging import getLogger import gevent from fcache.cache import FileCache from loggers import GCloudJsonFormatter, FIELDS_SKIPPED, DEFAULT_LOG_FORMATTER from loggers import get_logger from config import ConfigLoader from src.scaler import WorkerScaler logger = get_logger(name='') try: if os.getenv('KUBERNETES_SERVICE_HOST') is not None: for handler in logger.handlers: handler.setFormatter( GCloudJsonFormatter(reserved_attrs=FIELDS_SKIPPED, timestamp=True)) else: for handler in logger.handlers: handler.setFormatter(logging.Formatter(DEFAULT_LOG_FORMATTER)) except KeyError: pass class ScaleRunner: def __init__(self): self.config = ConfigLoader()
import sys import RPi.GPIO as GPIO import time import loggers from settings import rconn LOGGER = loggers.get_logger(__file__, loggers.get_debug_level()) TRIGGER_PIN = 23 ECHO_PIN = 24 SPEED_SOUND_CM = 17150 ######################################################## def startup(settle_time=2): LOGGER.info("startup") GPIO.setmode(GPIO.BCM) GPIO.setup(TRIGGER_PIN,GPIO.OUT) GPIO.setup(ECHO_PIN,GPIO.IN) GPIO.output(TRIGGER_PIN, False) LOGGER.info("Wait for sensor to settle after {0} seconds".format(settle_time)) time.sleep(settle_time) ######################################################## def shutdown(): LOGGER.info("shutdown") GPIO.cleanup() ######################################################## def read_distance(speed=SPEED_SOUND_CM):
def __init__(self): self.logger = loggers.get_logger(__name__)
from Tkinter import sys ###################################################################################################### # # Sabertooth Simplified Serial Mode # Because Sabertooth controls two motors with one 8 byte character, when operating in Simplified # Serial mode, each motor has 7 bits of resolution. # Sending a character between 1 and 127 will control motor 1. # 1 is full reverse, 64 is stop and 127 is full forward. # Sending a character between 128 and 255 will control motor 2. # 128 is full reverse, 192 is stop and 255 is full forward. # Character 0 (hex 0x00) is a special case. Sending this character will shut down both motors. # ###################################################################################################### LOGGER = loggers.get_logger(__file__, loggers.get_default_level()) conn = None # The serial communication connection object speedRange = range( 0, 65) # Requests for speed changes to either channel must be in this range STOPALL_COMMAND = 0 # This command will stop both motors, FULLREVERSE_M1 = 1 FULLSTOP_M1 = 64 FULLFORWARD_M1 = 127 FULLREVERSE_M2 = 128 FULLSTOP_M2 = 192 FULLFORWARD_M2 = 255
import socket import select import fakesocket from udptl import UDPTL, Handler from random import randint import hashlib import time from collections import deque from cPickle import dumps, loads from netaddr import IPAddress, IPNetwork, IPRange from loggers import get_logger, flush log = get_logger(__file__) CMD_NEIGHBORS = 'neighbors' class Ring(Handler): def __init__(self, nid, transport, addr=None): uid = 'ring' Handler.__init__(self, uid, transport, addr) self.nid = nid self.known_nodes = dict() self._msg_counter = randint(0, 10**4) self.queue = deque() def dispatch(self, uid, data, addr): print uid, data, addr if not data['address']: data['address'] = addr
import sys import time import loggers import motorctrl import diagnostics import commands from settings import rconn LOGGER = loggers.get_logger(__file__, loggers.get_default_level()) if __name__ == '__main__': try: motorctrl.startup() version = motorctrl.get_version() if version.ok == False: LOGGER.error("Failed to get version from motor controller") LOGGER.info("Let's start Driving with \"{0}\"".format(version.version)) motorctrl.set_voltage_settings(motorctrl.voltage_settings(0)) motorctrl.stop() LOGGER.info('starting queue processing mode') pubsub = rconn.pubsub() pubsub.subscribe('rover') while True: for item in pubsub.listen():
password = getpass.getpass("DigiCert Password: "******"Authentication failed. Unable to continue.") sys.exit() return r.data["api_key"] if __name__ == '__main__': try: main() print 'Finished' except Exception as ex: logger = loggers.get_logger(__name__) logger.debug("Expectedly ended operation with message: {0}".format(str(ex))) print "\nError occurred: {0}".format(str(ex)) except KeyboardInterrupt: print "\nProgram terminated by user" except SystemExit as sysex: pass except BaseException as bex: print str(bex)
import platform import sys import threading import distro import psutil from cpuinfo import cpuinfo import loggers import pynvml import repository logger = loggers.get_logger(__name__) _nvml_inited = False _static_info = {'public': {}, 'private': {}} _process_info = {} _process_info_lock = threading.Lock() def init(): global _nvml_inited _update_package_info() _update_platform_info() _update_psutil_static_info() try: pynvml.nvmlInit() _nvml_inited = True logger.info('[NVML] NVML Initialized') _update_nvml_static_info() except pynvml.NVMLError as e:
# -*- encoding:utf-8 -*- from texas_game import Player, Game import loggers import sys reload(sys) sys.setdefaultencoding('utf-8') # Rules blind_money = 2 max_players = 8 bet_limit = 50 game = Game() logger = loggers.get_logger() def game_info(): return game.info() def add_player(name, money=100): player = Player(name, money) game.add_player(player) if len(game.players) == 1: player.host = True game.log.append("%s 成为了房主" % player.print_name()) game.log.append("%s 加入了游戏" % player.print_name()) def start_game():