1import os 2import os.path as path 3import sys 4import uuid 5import configparser 6 7 8class ConfigError(Exception): 9 pass 10 11 12DEFAULT_API_URL = 'https://asciinema.org' 13DEFAULT_RECORD_ENV = 'SHELL,TERM' 14 15 16class Config: 17 18 def __init__(self, config_home, env=None): 19 self.config_home = config_home 20 self.config_file_path = path.join(config_home, "config") 21 self.install_id_path = path.join(self.config_home, 'install-id') 22 self.config = configparser.ConfigParser() 23 self.config.read(self.config_file_path) 24 self.env = env if env is not None else os.environ 25 26 def upgrade(self): 27 try: 28 self.install_id 29 except ConfigError: 30 id = self.__api_token() or self.__user_token() or self.__gen_install_id() 31 self.__save_install_id(id) 32 33 items = {name: dict(section) for (name, section) in self.config.items()} 34 if items == {'DEFAULT': {}, 'api': {'token': id}} or items == {'DEFAULT': {}, 'user': {'token': id}}: 35 os.remove(self.config_file_path) 36 37 if self.env.get('ASCIINEMA_API_TOKEN'): 38 raise ConfigError('ASCIINEMA_API_TOKEN variable is no longer supported, please use ASCIINEMA_INSTALL_ID instead') 39 40 def __read_install_id(self): 41 p = self.install_id_path 42 if path.isfile(p): 43 with open(p, 'r') as f: 44 return f.read().strip() 45 46 def __gen_install_id(self): 47 return str(uuid.uuid4()) 48 49 def __save_install_id(self, id): 50 self.__create_config_home() 51 52 with open(self.install_id_path, 'w') as f: 53 f.write(id) 54 55 def __create_config_home(self): 56 if not path.exists(self.config_home): 57 os.makedirs(self.config_home) 58 59 def __api_token(self): 60 try: 61 return self.config.get('api', 'token') 62 except (configparser.NoOptionError, configparser.NoSectionError): 63 pass 64 65 def __user_token(self): 66 try: 67 return self.config.get('user', 'token') 68 except (configparser.NoOptionError, configparser.NoSectionError): 69 pass 70 71 @property 72 def install_id(self): 73 id = self.env.get('ASCIINEMA_INSTALL_ID') or self.__read_install_id() 74 75 if id: 76 return id 77 else: 78 raise ConfigError('no install ID found') 79 80 @property 81 def api_url(self): 82 return self.env.get( 83 'ASCIINEMA_API_URL', 84 self.config.get('api', 'url', fallback=DEFAULT_API_URL) 85 ) 86 87 @property 88 def record_stdin(self): 89 return self.config.getboolean('record', 'stdin', fallback=False) 90 91 @property 92 def record_command(self): 93 return self.config.get('record', 'command', fallback=None) 94 95 @property 96 def record_env(self): 97 return self.config.get('record', 'env', fallback=DEFAULT_RECORD_ENV) 98 99 @property 100 def record_idle_time_limit(self): 101 fallback = self.config.getfloat('record', 'maxwait', fallback=None) # pre 2.0 102 return self.config.getfloat('record', 'idle_time_limit', fallback=fallback) 103 104 @property 105 def record_yes(self): 106 return self.config.getboolean('record', 'yes', fallback=False) 107 108 @property 109 def record_quiet(self): 110 return self.config.getboolean('record', 'quiet', fallback=False) 111 112 @property 113 def play_idle_time_limit(self): 114 fallback = self.config.getfloat('play', 'maxwait', fallback=None) # pre 2.0 115 return self.config.getfloat('play', 'idle_time_limit', fallback=fallback) 116 117 @property 118 def play_speed(self): 119 return self.config.getfloat('play', 'speed', fallback=1.0) 120 121 122def get_config_home(env=os.environ): 123 env_asciinema_config_home = env.get("ASCIINEMA_CONFIG_HOME") 124 env_xdg_config_home = env.get("XDG_CONFIG_HOME") 125 env_home = env.get("HOME") 126 127 config_home = None 128 129 if env_asciinema_config_home: 130 config_home = env_asciinema_config_home 131 elif env_xdg_config_home: 132 config_home = path.join(env_xdg_config_home, "asciinema") 133 elif env_home: 134 if path.isfile(path.join(env_home, ".asciinema", "config")): 135 # location for versions < 1.1 136 config_home = path.join(env_home, ".asciinema") 137 else: 138 config_home = path.join(env_home, ".config", "asciinema") 139 else: 140 raise Exception("need $HOME or $XDG_CONFIG_HOME or $ASCIINEMA_CONFIG_HOME") 141 142 return config_home 143 144 145def load(env=os.environ): 146 config = Config(get_config_home(env), env) 147 config.upgrade() 148 return config 149