| 1 | from logging import basicConfig, info, INFO, DEBUG, getLogger |
| 2 | from configparser import ConfigParser |
| 3 | from sys import platform, argv |
| 4 | from platform import system |
| 5 | from pathlib import Path |
| 6 | from glob import glob |
| 7 | from json import load, dumps |
| 8 | #from datetime import datetime |
| 9 | from pprint import pprint |
| 10 | from os import getcwd, environ |
| 11 | from os.path import exists, dirname |
| 12 | from traceback import print_stack |
| 13 | from sys import version_info |
| 14 | # from platform import system, release, architecture, platform, processor, \ |
| 15 | # version, machine |
| 16 | # from multiprocessing import cpu_count |
| 17 | from panda3d.core import Filename, GraphicsWindow, PandaSystem |
| 18 | from panda3d.bullet import get_bullet_version |
| 19 | from lib.gameobject import Colleague |
| 20 | from lib.lib.builder import LibP3d |
| 21 | import sys |
| 22 | |
| 23 | |
| 24 | lev = INFO |
| 25 | opt_path = '' |
| 26 | if platform in ['win32', 'linux'] and not exists('main.py'): |
| 27 | # it is the deployed version for windows |
| 28 | opt_path = str(Filename.get_user_appdata_directory()) + '/pmachines' |
| 29 | opath = LibP3d.fixpath(opt_path + '/options.ini') if opt_path else \ |
| 30 | 'options.ini' |
| 31 | if exists(opath): |
| 32 | with open(opath) as json_file: |
| 33 | #optfile = load(json_file) |
| 34 | optfile = ConfigParser() |
| 35 | optfile.read(opath) |
| 36 | # optfile['development']['verbose'] and int(optfile['development']['verbose']) or \ |
| 37 | if optfile['development']['verbose_log'] and int(optfile['development']['verbose_log']): |
| 38 | lev = DEBUG |
| 39 | |
| 40 | basicConfig(level=lev, format='%(asctime)s %(message)s', datefmt='%H:%M:%S') |
| 41 | getLogger().setLevel(lev) # it doesn't work otherwise |
| 42 | |
| 43 | |
| 44 | class LogMgrBase(Colleague): # headless log manager |
| 45 | |
| 46 | @staticmethod |
| 47 | def init_cls(): |
| 48 | return LogMgr if base.win else LogMgrBase |
| 49 | |
| 50 | def __init__(self, mediator): |
| 51 | Colleague.__init__(self, mediator) |
| 52 | self.log_cfg() |
| 53 | |
| 54 | def log(self, msg, verbose=False): |
| 55 | if verbose and not self.eng.cfg.dev_cfg.verbose_log: return |
| 56 | info(msg) |
| 57 | |
| 58 | @property |
| 59 | def is_appimage(self): |
| 60 | par_path = str(Path(__file__).parent.absolute()) |
| 61 | is_appimage = par_path.startswith('/tmp/.mount_Pmachi') |
| 62 | return is_appimage and par_path.endswith('/usr/bin') |
| 63 | |
| 64 | # @property |
| 65 | # def curr_path(self): |
| 66 | # # this is different from the music's one since it does not work |
| 67 | # # with the version in windows |
| 68 | # if sys.platform == 'darwin': |
| 69 | # return dirname(__file__) + '/../Resources/' |
| 70 | # # return dirname(__file__) |
| 71 | # par_path = str(Path(__file__).parent.absolute()) |
| 72 | # if self.is_appimage: |
| 73 | # return str(Path(par_path).absolute()) |
| 74 | # is_snap = par_path.startswith('/snap/') |
| 75 | # is_snap = is_snap and par_path.endswith('/x1') |
| 76 | # if is_snap: |
| 77 | # return str(Path(par_path).absolute()) |
| 78 | # #return getcwd() |
| 79 | # #curr_path = dirname(__file__) |
| 80 | # curr_path = str(Path(__file__).parent.parent.parent.absolute()) |
| 81 | # info('current path: %s' % curr_path) |
| 82 | # return curr_path |
| 83 | |
| 84 | @property |
| 85 | def curr_path(self): |
| 86 | if system() == 'Windows': |
| 87 | return '' |
| 88 | if exists('main.py'): |
| 89 | return '' |
| 90 | else: |
| 91 | par_path = str(Path(__file__).parent.absolute()) |
| 92 | if self.is_appimage: |
| 93 | par_path = str(Path(par_path).absolute()) |
| 94 | par_path += '/' |
| 95 | return par_path |
| 96 | |
| 97 | @property |
| 98 | def build_version(self): |
| 99 | appimg_mnt = glob('/tmp/.mount_Pmachi*') |
| 100 | if appimg_mnt: |
| 101 | #with open(appimg_mnt[0] + '/usr/bin/appimage_version.txt') as fver: |
| 102 | with open(self.curr_path + 'assets/bld_version.txt') as fver: |
| 103 | return fver.read().strip() |
| 104 | try: |
| 105 | with open(self.curr_path + 'assets/bld_version.txt') as fver: |
| 106 | return fver.read().strip() |
| 107 | except FileNotFoundError: |
| 108 | info('not found ' + self.curr_path + 'assets/bld_version.txt') |
| 109 | return 'notfound' |
| 110 | |
| 111 | def log_cfg(self): |
| 112 | if '--version' in argv: |
| 113 | path = str(Filename.get_user_appdata_directory()) |
| 114 | home = '/home/flavio' # we must force this for wine |
| 115 | if path.startswith('/c/users/') and exists(home + '/.wine/'): |
| 116 | path = home + '/.wine/drive_' + path[1:] |
| 117 | info('writing %s' % path + '/pmachines/obs_version.txt') |
| 118 | with open(path + '/pmachines/obs_version.txt', 'w') as f: |
| 119 | #f.write(self.eng.logic.version) |
| 120 | f.write(self.build_version) |
| 121 | if not platform.startswith('win'): |
| 122 | from os import ttyname # here because it doesn't work on windows |
| 123 | import sys |
| 124 | with open(ttyname(0), 'w') as fout: |
| 125 | sys.stdout = fout |
| 126 | print('version: ' + self.build_version) # self.eng.logic.version) |
| 127 | messages = ['version: ' + self.build_version] # self.eng.logic.version] |
| 128 | messages += ['argv[0]: %s' % argv[0]] |
| 129 | messages += ['getcwd: %s' % getcwd()] |
| 130 | messages += ['__file__: %s' % __file__] |
| 131 | for elm in environ.items(): |
| 132 | messages += ['env::%s: %s' % elm] |
| 133 | # os_info = (system(), release(), version()) |
| 134 | # messages += ['operative system: %s %s %s' % os_info] |
| 135 | # messages += ['architecture: ' + str(architecture())] |
| 136 | # messages += ['machine: ' + machine()] |
| 137 | # messages += ['platform: ' + platform()] |
| 138 | # messages += ['processor: ' + processor()] |
| 139 | # try: |
| 140 | # messages += ['cores: ' + str(cpu_count())] |
| 141 | # except NotImplementedError: # on Windows |
| 142 | # messages += ['cores: not implemented'] |
| 143 | lib_ver = PandaSystem.get_version_string() |
| 144 | try: |
| 145 | import psutil |
| 146 | mem = psutil.virtual_memory().total / 1000000000.0 |
| 147 | messages += ['memory: %s GB' % round(mem, 2)] |
| 148 | except ImportError: info("can't import psutil") # windows |
| 149 | lib_commit = PandaSystem.get_git_commit() |
| 150 | py_ver = [str(elm) for elm in version_info[:3]] |
| 151 | messages += ['python version: %s' % '.'.join(py_ver)] |
| 152 | messages += ['panda version: %s %s' % (lib_ver, lib_commit)] |
| 153 | messages += ['bullet version: ' + str(get_bullet_version())] |
| 154 | messages += ['appdata: ' + str(Filename.get_user_appdata_directory())] |
| 155 | if base.win and isinstance(base.win, GraphicsWindow): # not headless |
| 156 | print(base.win.get_keyboard_map()) |
| 157 | list(map(self.log, messages)) |
| 158 | |
| 159 | @staticmethod |
| 160 | def log_tasks(): |
| 161 | info('tasks: %s' % taskMgr.getAllTasks()) |
| 162 | info('do-laters: %s' % taskMgr.getDoLaters()) |
| 163 | |
| 164 | @staticmethod |
| 165 | def plog(obj): |
| 166 | print('\n\n') |
| 167 | print_stack() |
| 168 | pprint(obj) |
| 169 | print('\n\n') |
| 170 | |
| 171 | |
| 172 | class LogMgr(LogMgrBase): |
| 173 | |
| 174 | def log_cfg(self): |
| 175 | LogMgrBase.log_cfg(self) |
| 176 | messages = [base.win.get_gsg().get_driver_vendor()] |
| 177 | messages += [base.win.get_gsg().get_driver_renderer()] |
| 178 | shad_maj = base.win.get_gsg().get_driver_shader_version_major() |
| 179 | shad_min = base.win.get_gsg().get_driver_shader_version_minor() |
| 180 | messages += ['shader: {maj}.{min}'.format(maj=shad_maj, min=shad_min)] |
| 181 | messages += [base.win.get_gsg().get_driver_version()] |
| 182 | drv_maj = base.win.get_gsg().get_driver_version_major() |
| 183 | drv_min = base.win.get_gsg().get_driver_version_minor() |
| 184 | drv = 'driver version: {maj}.{min}' |
| 185 | messages += [drv.format(maj=drv_maj, min=drv_min)] |
| 186 | fullscreen = None |
| 187 | if isinstance(base.win, GraphicsWindow): |
| 188 | fullscreen = base.win.get_properties().get_fullscreen() |
| 189 | messages += ['fullscreen: ' + str(fullscreen)] |
| 190 | def resolution(): |
| 191 | if not isinstance(base.win, GraphicsWindow): |
| 192 | return 800, 600 |
| 193 | win_prop = base.win.get_properties() |
| 194 | return win_prop.get_x_size(), win_prop.get_y_size() |
| 195 | res_x, res_y = resolution() |
| 196 | res_tmpl = 'resolution: {res_x}x{res_y}' |
| 197 | messages += [res_tmpl.format(res_x=res_x, res_y=res_y)] |
| 198 | list(map(self.log, messages)) |