| 1 | # vim: set expandtab shiftwidth=4 softtabstop=4:
|
|---|
| 2 |
|
|---|
| 3 | # === UCSF ChimeraX Copyright ===
|
|---|
| 4 | # Copyright 2016 Regents of the University of California.
|
|---|
| 5 | # All rights reserved. This software provided pursuant to a
|
|---|
| 6 | # license agreement containing restrictions on its disclosure,
|
|---|
| 7 | # duplication and use. For details see:
|
|---|
| 8 | # http://www.rbvi.ucsf.edu/chimerax/docs/licensing.html
|
|---|
| 9 | # This notice must be embedded in or attached to all copies,
|
|---|
| 10 | # including partial copies, of the software or any revisions
|
|---|
| 11 | # or derivations thereof.
|
|---|
| 12 | # === UCSF ChimeraX Copyright ===
|
|---|
| 13 |
|
|---|
| 14 | from chimerax.core.commands import CmdDesc, register, Command, OpenFileNamesArg, RestOfLine, next_token, \
|
|---|
| 15 | FileNameArg, BoolArg, StringArg, DynamicEnum
|
|---|
| 16 | from chimerax.core.commands.cli import RegisteredCommandInfo
|
|---|
| 17 | from chimerax.core.errors import UserError, LimitationError
|
|---|
| 18 |
|
|---|
| 19 | # need to use non-repeatable OpenFilesNamesArg (rather than OpenFileNameArg) so that 'browse' can still be
|
|---|
| 20 | # used to open multiple files
|
|---|
| 21 | class OpenFileNamesArgNoRepeat(OpenFileNamesArg):
|
|---|
| 22 | allow_repeat = False
|
|---|
| 23 |
|
|---|
| 24 | import os.path
|
|---|
| 25 | def likely_pdb_id(text):
|
|---|
| 26 | return not os.path.exists(text) and len(text) == 4 and text[0].isdigit() and text[1:].isalnum()
|
|---|
| 27 |
|
|---|
| 28 | def cmd_open(session, file_names, rest_of_line, *, log=True):
|
|---|
| 29 | tokens = []
|
|---|
| 30 | remainder = rest_of_line
|
|---|
| 31 | while remainder:
|
|---|
| 32 | token, token_log, remainder = next_token(remainder)
|
|---|
| 33 | remainder = remainder.lstrip()
|
|---|
| 34 | tokens.append(token)
|
|---|
| 35 | database_name = format_name = None
|
|---|
| 36 | for i in range(len(tokens)-2, -1, -2):
|
|---|
| 37 | test_token = tokens[i].lower()
|
|---|
| 38 | if "format".startswith(test_token):
|
|---|
| 39 | format_name = tokens[i+1]
|
|---|
| 40 | elif "fromdatabase".startswith(test_token):
|
|---|
| 41 | database_name = tokens[i+1]
|
|---|
| 42 |
|
|---|
| 43 | from .manager import NoOpenerError
|
|---|
| 44 | mgr = session.open_command
|
|---|
| 45 | fetches, files = fetches_vs_files(mgr, file_names, format_name, database_name)
|
|---|
| 46 | if fetches:
|
|---|
| 47 | try:
|
|---|
| 48 | provider_args = mgr.fetch_args(fetches[0][1], format_name=fetches[0][2])
|
|---|
| 49 | except NoOpenerError as e:
|
|---|
| 50 | raise LimitationError(str(e))
|
|---|
| 51 | else:
|
|---|
| 52 | data_format = file_format(session, files[0], format_name)
|
|---|
| 53 | if data_format is None:
|
|---|
| 54 | # let provider_open raise the error, which will show the command
|
|---|
| 55 | provider_args = {}
|
|---|
| 56 | else:
|
|---|
| 57 | try:
|
|---|
| 58 | provider_args = mgr.open_args(data_format)
|
|---|
| 59 | except NoOpenerError as e:
|
|---|
| 60 | raise LimitationError(str(e))
|
|---|
| 61 |
|
|---|
| 62 | provider_cmd_text = "open " + " ".join([FileNameArg.unparse(fn)
|
|---|
| 63 | for fn in file_names] + tokens)
|
|---|
| 64 | # register a private 'open' command that handles the provider's keywords
|
|---|
| 65 | registry = RegisteredCommandInfo()
|
|---|
| 66 | def format_names(ses=session):
|
|---|
| 67 | fmt_names = set([ fmt.nicknames[0] for fmt in ses.open_command.open_data_formats ])
|
|---|
| 68 | for db_name in ses.open_command.database_names:
|
|---|
| 69 | for fmt_name in ses.open_command.database_info(db_name).keys():
|
|---|
| 70 | fmt_names.add(ses.data_formats[fmt_name].nicknames[0])
|
|---|
| 71 | return fmt_names
|
|---|
| 72 |
|
|---|
| 73 | def database_names(mgr=mgr):
|
|---|
| 74 | return mgr.database_names
|
|---|
| 75 |
|
|---|
| 76 | keywords = {
|
|---|
| 77 | 'format': DynamicEnum(format_names),
|
|---|
| 78 | 'from_database': DynamicEnum(database_names),
|
|---|
| 79 | 'ignore_cache': BoolArg,
|
|---|
| 80 | 'name': StringArg
|
|---|
| 81 | }
|
|---|
| 82 | for keyword, annotation in provider_args.items():
|
|---|
| 83 | if keyword in keywords:
|
|---|
| 84 | raise ValueError("Open-provider keyword '%s' conflicts with builtin arg of"
|
|---|
| 85 | " same name" % keyword)
|
|---|
| 86 | keywords[keyword] = annotation
|
|---|
| 87 | desc = CmdDesc(required=[('names', OpenFileNamesArg)], keyword=keywords.items(),
|
|---|
| 88 | synopsis="unnecessary")
|
|---|
| 89 | register("open", desc, provider_open, registry=registry)
|
|---|
| 90 | Command(session, registry=registry).run(provider_cmd_text, log=log)
|
|---|
| 91 |
|
|---|
| 92 | def provider_open(session, names, format=None, from_database=None, ignore_cache=False,
|
|---|
| 93 | name=None, _return_status=False, _add_models=True, **provider_kw):
|
|---|
| 94 | mgr = session.open_command
|
|---|
| 95 | # since the "file names" may be globs, need to preprocess them...
|
|---|
| 96 | fetches, file_names = fetches_vs_files(mgr, names, format, from_database)
|
|---|
| 97 | file_infos = [FileInfo(session, fn, format) for fn in file_names]
|
|---|
| 98 | formats = set([fi.data_format for fi in file_infos])
|
|---|
| 99 | databases = set([f[1:] for f in fetches])
|
|---|
| 100 | homogeneous = len(formats) + len(databases) == 1
|
|---|
| 101 | if provider_kw and not homogeneous:
|
|---|
| 102 | raise UserError("Cannot provide format/database-specific keywords when opening"
|
|---|
| 103 | " multiple different formats or databases; use several 'open' commands"
|
|---|
| 104 | " instead.")
|
|---|
| 105 | opened_models = []
|
|---|
| 106 | statuses = []
|
|---|
| 107 | if homogeneous:
|
|---|
| 108 | data_format = formats.pop() if formats else None
|
|---|
| 109 | database_name, format = databases.pop() if databases else (None, format)
|
|---|
| 110 | if database_name:
|
|---|
| 111 | fetcher_info, default_format_name = _fetch_info(mgr, database_name, format)
|
|---|
| 112 | for ident, database_name, format_name in fetches:
|
|---|
| 113 | if format_name is None:
|
|---|
| 114 | format_name = default_format_name
|
|---|
| 115 | models, status = collated_open(session, database_name, ident,
|
|---|
| 116 | session.data_formats[format_name], _add_models, fetcher_info.fetch,
|
|---|
| 117 | (session, ident, format_name, ignore_cache), provider_kw)
|
|---|
| 118 | if status:
|
|---|
| 119 | statuses.append(status)
|
|---|
| 120 | if models:
|
|---|
| 121 | opened_models.append(name_and_group_models(models, name, [ident]))
|
|---|
| 122 | else:
|
|---|
| 123 | opener_info, provider_info = mgr.open_info(data_format)
|
|---|
| 124 | if provider_info.batch:
|
|---|
| 125 | paths = [_get_path(mgr, fi.file_name, provider_info.check_path)
|
|---|
| 126 | for fi in file_infos]
|
|---|
| 127 | models, status = collated_open(session, None, paths, data_format, _add_models,
|
|---|
| 128 | opener_info.open, (session, paths, name), provider_kw)
|
|---|
| 129 | if status:
|
|---|
| 130 | statuses.append(status)
|
|---|
| 131 | if models:
|
|---|
| 132 | opened_models.append(name_and_group_models(models, name, paths))
|
|---|
| 133 | else:
|
|---|
| 134 | for fi in file_infos:
|
|---|
| 135 | if provider_info.want_path:
|
|---|
| 136 | data = _get_path(mgr, fi.file_name, provider_info.check_path)
|
|---|
| 137 | else:
|
|---|
| 138 | data = _get_stream(mgr, fi.file_name, data_format.encoding)
|
|---|
| 139 | models, status = collated_open(session, None, [data], data_format, _add_models,
|
|---|
| 140 | opener_info.open, (session, data,
|
|---|
| 141 | name or model_name_from_path(fi.file_name)), provider_kw)
|
|---|
| 142 | if status:
|
|---|
| 143 | statuses.append(status)
|
|---|
| 144 | if models:
|
|---|
| 145 | opened_models.append(name_and_group_models(models, name,
|
|---|
| 146 | [fi.file_name]))
|
|---|
| 147 | else:
|
|---|
| 148 | for fi in file_infos:
|
|---|
| 149 | opener_info, provider_info = mgr.open_info(fi.data_format)
|
|---|
| 150 | if provider_info.want_path:
|
|---|
| 151 | data = _get_path(mgr, fi.file_name, provider_info.check_path)
|
|---|
| 152 | else:
|
|---|
| 153 | data = _get_stream(mgr, fi.file_name, fi.data_format.encoding)
|
|---|
| 154 | models, status = collated_open(session, None, [data], fi.data_format, _add_models,
|
|---|
| 155 | opener_info.open, (session, data, name or model_name_from_path(fi.file_name)), provider_kw)
|
|---|
| 156 | if status:
|
|---|
| 157 | statuses.append(status)
|
|---|
| 158 | if models:
|
|---|
| 159 | opened_models.append(name_and_group_models(models, name, [fi.file_name]))
|
|---|
| 160 | for ident, database_name, format_name in fetches:
|
|---|
| 161 | fetcher_info, default_format_name = _fetch_info(mgr, database_name, format)
|
|---|
| 162 | if format_name is None:
|
|---|
| 163 | format_name = default_format_name
|
|---|
| 164 | models, status = collated_open(session, database_name, ident, session.data_formats[format_name],
|
|---|
| 165 | _add_models, fetcher_info.fetch, (session, ident, format_name, ignore_cache), provider_kw)
|
|---|
| 166 | if status:
|
|---|
| 167 | statuses.append(status)
|
|---|
| 168 | if models:
|
|---|
| 169 | opened_models.append(name_and_group_models(models, name, [ident]))
|
|---|
| 170 | if opened_models and _add_models:
|
|---|
| 171 | session.models.add(opened_models)
|
|---|
| 172 | if _add_models and len(names) == 1:
|
|---|
| 173 | # TODO: Handle lists of file names in history
|
|---|
| 174 | from chimerax.core.filehistory import remember_file
|
|---|
| 175 | if fetches:
|
|---|
| 176 | # Files opened in the help browser are done asynchronously and might have
|
|---|
| 177 | # been misspelled and can't be deleted from file history. So skip them.
|
|---|
| 178 | if not statuses or not statuses[-1].endswith(" in browser"):
|
|---|
| 179 | remember_file(session, names[0], session.data_formats[format_name].nicknames[0],
|
|---|
| 180 | opened_models or 'all models', database=database_name,
|
|---|
| 181 | open_options=provider_kw)
|
|---|
| 182 | else:
|
|---|
| 183 | remember_file(session, names[0], file_infos[0].data_format.nicknames[0],
|
|---|
| 184 | opened_models or 'all models', open_options=provider_kw)
|
|---|
| 185 |
|
|---|
| 186 | status ='\n'.join(statuses) if statuses else ""
|
|---|
| 187 | if _return_status:
|
|---|
| 188 | return opened_models, status
|
|---|
| 189 | elif status:
|
|---|
| 190 | session.logger.status(status, log=True)
|
|---|
| 191 | return opened_models
|
|---|
| 192 |
|
|---|
| 193 | def _fetch_info(mgr, database_name, default_format_name):
|
|---|
| 194 | db_info = mgr.database_info(database_name)
|
|---|
| 195 | from chimerax.core.commands import commas
|
|---|
| 196 | if default_format_name:
|
|---|
| 197 | try:
|
|---|
| 198 | provider_info = db_info[default_format_name]
|
|---|
| 199 | except KeyError:
|
|---|
| 200 | raise UserError("Format '%s' not available for database '%s'. Available"
|
|---|
| 201 | " formats are: %s" % (default_format_name, database_name,
|
|---|
| 202 | commas(db_info.keys())))
|
|---|
| 203 | else:
|
|---|
| 204 | for default_format_name, provider_info in db_info.items():
|
|---|
| 205 | if provider_info.is_default:
|
|---|
| 206 | break
|
|---|
| 207 | else:
|
|---|
| 208 | raise UserError("No default format for database '%s'. Possible formats are:"
|
|---|
| 209 | " %s" % (database_name, commas(db_info.keys())))
|
|---|
| 210 | return (provider_info.bundle_info.run_provider(mgr.session, database_name, mgr),
|
|---|
| 211 | default_format_name)
|
|---|
| 212 |
|
|---|
| 213 | def _get_path(mgr, file_name, check_path, check_compression=True):
|
|---|
| 214 | from os.path import expanduser, expandvars, exists
|
|---|
| 215 | expanded = expanduser(expandvars(file_name))
|
|---|
| 216 | from chimerax.io import file_system_file_name
|
|---|
| 217 | if check_path and not exists(file_system_file_name(expanded)):
|
|---|
| 218 | raise UserError("No such file/path: %s" % file_name)
|
|---|
| 219 |
|
|---|
| 220 | if check_compression:
|
|---|
| 221 | from chimerax import io
|
|---|
| 222 | if io.remove_compression_suffix(expanded) != expanded:
|
|---|
| 223 | raise UserError("File reader requires uncompressed file; '%s' is compressed"
|
|---|
| 224 | % file_name)
|
|---|
| 225 | return expanded
|
|---|
| 226 |
|
|---|
| 227 | def _get_stream(mgr, file_name, encoding):
|
|---|
| 228 | path = _get_path(mgr, file_name, True, check_compression=False)
|
|---|
| 229 | from chimerax import io
|
|---|
| 230 | return io.open_input(path, encoding)
|
|---|
| 231 |
|
|---|
| 232 | def fetches_vs_files(mgr, names, format_name, database_name):
|
|---|
| 233 | fetches = []
|
|---|
| 234 | files = []
|
|---|
| 235 | from os.path import exists
|
|---|
| 236 | for name in names:
|
|---|
| 237 | if not database_name and exists(name):
|
|---|
| 238 | print("no database and exists[1]")
|
|---|
| 239 | files.append(name)
|
|---|
| 240 | else:
|
|---|
| 241 | f = fetch_info(mgr, name, format_name, database_name)
|
|---|
| 242 | if f:
|
|---|
| 243 | fetches.append(f)
|
|---|
| 244 | else:
|
|---|
| 245 | files.extend(expand_path(name))
|
|---|
| 246 | return fetches, files
|
|---|
| 247 |
|
|---|
| 248 | def expand_path(file_name):
|
|---|
| 249 | from os.path import exists
|
|---|
| 250 | if exists(file_name):
|
|---|
| 251 | return [file_name]
|
|---|
| 252 |
|
|---|
| 253 | from glob import glob
|
|---|
| 254 | file_names = glob(file_name)
|
|---|
| 255 | if not file_names:
|
|---|
| 256 | return [file_name]
|
|---|
| 257 | # python glob does not sort. Keep series in order
|
|---|
| 258 | file_names.sort()
|
|---|
| 259 | return file_names
|
|---|
| 260 |
|
|---|
| 261 | def fetch_info(mgr, file_arg, format_name, database_name):
|
|---|
| 262 | from os.path import exists
|
|---|
| 263 | if not database_name and exists(file_arg):
|
|---|
| 264 | print("no database and exists[2]")
|
|---|
| 265 | return None
|
|---|
| 266 | print("Likely PDB ID for '%s':" % (file_arg, likely_pdb_id(file_arg)))
|
|---|
| 267 | if ':' in file_arg:
|
|---|
| 268 | db_name, ident = file_arg.split(':', maxsplit=1)
|
|---|
| 269 | elif database_name:
|
|---|
| 270 | db_name = database_name
|
|---|
| 271 | ident = file_arg
|
|---|
| 272 | elif likely_pdb_id(file_arg):
|
|---|
| 273 | db_name = "pdb"
|
|---|
| 274 | ident = file_arg
|
|---|
| 275 | else:
|
|---|
| 276 | return None
|
|---|
| 277 | from .manager import NoOpenerError
|
|---|
| 278 | try:
|
|---|
| 279 | db_formats = list(mgr.database_info(db_name).keys())
|
|---|
| 280 | except NoOpenerError as e:
|
|---|
| 281 | raise LimitationError(str(e))
|
|---|
| 282 | if format_name and format_name not in db_formats:
|
|---|
| 283 | # for backwards compatibiity, accept formal format name or nicknames
|
|---|
| 284 | try:
|
|---|
| 285 | df = mgr.session.data_formats[format_name]
|
|---|
| 286 | except KeyError:
|
|---|
| 287 | nicks = []
|
|---|
| 288 | else:
|
|---|
| 289 | nicks = df.nicknames + [df.name]
|
|---|
| 290 | for nick in nicks:
|
|---|
| 291 | if nick in db_formats:
|
|---|
| 292 | format_name = nick
|
|---|
| 293 | break
|
|---|
| 294 | else:
|
|---|
| 295 | from chimerax.core.commands import commas
|
|---|
| 296 | raise UserError("Format '%s' not supported for database '%s'. Supported"
|
|---|
| 297 | " formats are: %s" % (format_name, db_name,
|
|---|
| 298 | commas([dbf for dbf in db_formats])))
|
|---|
| 299 | return (ident, db_name, format_name)
|
|---|
| 300 |
|
|---|
| 301 | def name_and_group_models(models, name_arg, path_info):
|
|---|
| 302 | if len(models) > 1:
|
|---|
| 303 | # name arg only applies to group, not underlings
|
|---|
| 304 | if name_arg:
|
|---|
| 305 | names = [name_arg] * len(models)
|
|---|
| 306 | elif len(path_info) == len(models):
|
|---|
| 307 | names = [model_name_from_path(p) for p in path_info]
|
|---|
| 308 | else:
|
|---|
| 309 | names = [model_name_from_path(path_info[0])] * len(models)
|
|---|
| 310 | for m, pn in zip(models, names):
|
|---|
| 311 | if name_arg or not m.name:
|
|---|
| 312 | m.name = pn
|
|---|
| 313 | from chimerax.core.models import Model
|
|---|
| 314 | names = set([m.name for m in models])
|
|---|
| 315 | if len(names) == 1:
|
|---|
| 316 | group_name = names.pop() + " group"
|
|---|
| 317 | elif len(path_info) == 1:
|
|---|
| 318 | group_name = model_name_from_path(path_info[0])
|
|---|
| 319 | else:
|
|---|
| 320 | group_name = "group"
|
|---|
| 321 | group = Model(group_name, models[0].session)
|
|---|
| 322 | group.add(models)
|
|---|
| 323 | return group
|
|---|
| 324 | model = models[0]
|
|---|
| 325 | if name_arg:
|
|---|
| 326 | model.name = name_arg
|
|---|
| 327 | else:
|
|---|
| 328 | if not model.name:
|
|---|
| 329 | model.name = model_name_from_path(path_info[0])
|
|---|
| 330 | return model
|
|---|
| 331 |
|
|---|
| 332 | def model_name_from_path(path):
|
|---|
| 333 | from os.path import basename, dirname
|
|---|
| 334 | name = basename(path)
|
|---|
| 335 | if name.strip() == '':
|
|---|
| 336 | # Path is a directory with trailing '/'. Use directory name.
|
|---|
| 337 | name = basename(dirname(path))
|
|---|
| 338 | return name
|
|---|
| 339 |
|
|---|
| 340 | def file_format(session, file_name, format_name):
|
|---|
| 341 | if format_name:
|
|---|
| 342 | try:
|
|---|
| 343 | return session.data_formats[format_name]
|
|---|
| 344 | except KeyError:
|
|---|
| 345 | return None
|
|---|
| 346 |
|
|---|
| 347 | from chimerax.data_formats import NoFormatError
|
|---|
| 348 | try:
|
|---|
| 349 | return session.data_formats.open_format_from_file_name(file_name)
|
|---|
| 350 | except NoFormatError as e:
|
|---|
| 351 | return None
|
|---|
| 352 |
|
|---|
| 353 | def collated_open(session, database_name, data, data_format, main_opener, func, func_args, func_kw):
|
|---|
| 354 | is_script = data_format.category == session.data_formats.CAT_SCRIPT
|
|---|
| 355 | if is_script:
|
|---|
| 356 | with session.in_script:
|
|---|
| 357 | return func(*func_args, **func_kw)
|
|---|
| 358 | from chimerax.core.logger import Collator
|
|---|
| 359 | if database_name:
|
|---|
| 360 | description = "Summary of feedback from opening %s fetched from %s" % (data, database_name)
|
|---|
| 361 | else:
|
|---|
| 362 | if len(data) > 1:
|
|---|
| 363 | opened_text = "files"
|
|---|
| 364 | else:
|
|---|
| 365 | if isinstance(data[0], str):
|
|---|
| 366 | opened_text = data[0]
|
|---|
| 367 | elif hasattr(data[0], 'name'):
|
|---|
| 368 | opened_text = data[0].name
|
|---|
| 369 | else:
|
|---|
| 370 | opened_text = "input"
|
|---|
| 371 | description = "Summary of feedback from opening %s" % opened_text
|
|---|
| 372 | if main_opener:
|
|---|
| 373 | with Collator(session.logger, description, True):
|
|---|
| 374 | return func(*func_args, **func_kw)
|
|---|
| 375 | return func(*func_args, **func_kw)
|
|---|
| 376 |
|
|---|
| 377 | class FileInfo:
|
|---|
| 378 | def __init__(self, session, file_name, format_name):
|
|---|
| 379 | self.file_name = file_name
|
|---|
| 380 | self.data_format = file_format(session, file_name, format_name)
|
|---|
| 381 | if self.data_format is None:
|
|---|
| 382 | from os.path import splitext
|
|---|
| 383 | from chimerax import io
|
|---|
| 384 | ext = splitext(io.remove_compression_suffix(file_name))[1]
|
|---|
| 385 | if ext:
|
|---|
| 386 | raise UserError("Unrecognized file suffix '%s'" % ext)
|
|---|
| 387 | raise UserError("'%s' has no suffix" % file_name)
|
|---|
| 388 |
|
|---|
| 389 | def cmd_open_formats(session):
|
|---|
| 390 | '''Report file formats, suffixes and databases that the open command knows about.'''
|
|---|
| 391 | if session.ui.is_gui:
|
|---|
| 392 | lines = ['<table border=1 cellspacing=0 cellpadding=2>', '<tr><th>File format<th>Short name(s)<th>Suffixes']
|
|---|
| 393 | else:
|
|---|
| 394 | session.logger.info('File format, Short name(s), Suffixes:')
|
|---|
| 395 | from chimerax.core.commands import commas
|
|---|
| 396 | formats = session.open_command.open_data_formats
|
|---|
| 397 | formats.sort(key = lambda f: f.name.lower())
|
|---|
| 398 | for f in formats:
|
|---|
| 399 | if session.ui.is_gui:
|
|---|
| 400 | from html import escape
|
|---|
| 401 | if f.reference_url:
|
|---|
| 402 | descrip = '<a href="%s">%s</a>' % (f.reference_url, escape(f.synopsis))
|
|---|
| 403 | else:
|
|---|
| 404 | descrip = escape(f.synopsis)
|
|---|
| 405 | lines.append('<tr><td>%s<td>%s<td>%s' % (descrip,
|
|---|
| 406 | escape(commas(f.nicknames)), escape(', '.join(f.suffixes))))
|
|---|
| 407 | else:
|
|---|
| 408 | session.logger.info(' %s: %s: %s' % (f.synopsis,
|
|---|
| 409 | commas(f.nicknames), ', '.join(f.suffixes)))
|
|---|
| 410 | if session.ui.is_gui:
|
|---|
| 411 | lines.append('</table>')
|
|---|
| 412 | lines.append('<p></p>')
|
|---|
| 413 |
|
|---|
| 414 | if session.ui.is_gui:
|
|---|
| 415 | lines.extend(['<table border=1 cellspacing=0 cellpadding=2>', '<tr><th>Database<th>Formats'])
|
|---|
| 416 | else:
|
|---|
| 417 | session.logger.info('\nDatabase, Formats:')
|
|---|
| 418 | database_names = session.open_command.database_names
|
|---|
| 419 | database_names.sort(key=lambda dbn: dbn.lower())
|
|---|
| 420 | for db_name in database_names:
|
|---|
| 421 | db_info = session.open_command.database_info(db_name)
|
|---|
| 422 | if 'web fetch' in db_info.keys() or db_name == 'help':
|
|---|
| 423 | continue
|
|---|
| 424 | for fmt_name, fetcher_info in db_info.items():
|
|---|
| 425 | if fetcher_info.is_default:
|
|---|
| 426 | default_name = session.data_formats[fmt_name].nicknames[0]
|
|---|
| 427 | break
|
|---|
| 428 | else:
|
|---|
| 429 | continue
|
|---|
| 430 | format_names = [session.data_formats[fmt_name].nicknames[0] for fmt_name in db_info.keys()]
|
|---|
| 431 | format_names.sort()
|
|---|
| 432 | format_names.remove(default_name)
|
|---|
| 433 | format_names.insert(0, default_name)
|
|---|
| 434 | if not session.ui.is_gui:
|
|---|
| 435 | session.logger.info(' %s: %s' % (db_name, ', '.join(format_names)))
|
|---|
| 436 | continue
|
|---|
| 437 | line = '<tr><td>%s<td>%s' % (db_name, ', '.join(format_names))
|
|---|
| 438 | lines.append(line)
|
|---|
| 439 |
|
|---|
| 440 | if session.ui.is_gui:
|
|---|
| 441 | lines.append('</table>')
|
|---|
| 442 | msg = '\n'.join(lines)
|
|---|
| 443 | session.logger.info(msg, is_html=True)
|
|---|
| 444 |
|
|---|
| 445 |
|
|---|
| 446 | def register_command(command_name, logger):
|
|---|
| 447 | register('open', CmdDesc(required=[('file_names', OpenFileNamesArgNoRepeat),
|
|---|
| 448 | ('rest_of_line', RestOfLine)], synopsis="Open/fetch data files",
|
|---|
| 449 | self_logging=True), cmd_open, logger=logger)
|
|---|
| 450 |
|
|---|
| 451 | of_desc = CmdDesc(synopsis='report formats that can be opened')
|
|---|
| 452 | register('open formats', of_desc, cmd_open_formats, logger=logger)
|
|---|