def shell_cmd(verbose, with_req_context): try: from IPython.terminal.ipapp import TerminalIPythonApp except ImportError: click.echo( cformat( '%{red!}You need to `pip install ipython` to use the fossir shell' )) sys.exit(1) current_app.config['REPL'] = True # disables e.g. memoize_request request_stats_request_started() context, info = _make_shell_context() banner = cformat('%{yellow!}fossir v{} is ready for your commands').format( fossir.__version__) if verbose: banner = '\n'.join(info + ['', banner]) ctx = current_app.make_shell_context() ctx.update(context) clearCache() stack = ExitStack() if with_req_context: stack.enter_context( current_app.test_request_context(base_url=config.BASE_URL)) with stack: ipython_app = TerminalIPythonApp.instance(user_ns=ctx, display_banner=False) ipython_app.initialize(argv=[]) ipython_app.shell.show_banner(banner) ipython_app.start()
def _call_with_plugins(*args, **kwargs): func = kwargs.pop('_func') ctx = click.get_current_context() all_plugins = ctx.parent.params['all_plugins'] plugin = ctx.parent.params['plugin'] if plugin: plugins = {plugin_engine.get_plugin(plugin)} elif all_plugins: plugins = set(plugin_engine.get_active_plugins().viewvalues()) else: plugins = None if plugins is None: func(*args, **kwargs) else: PluginScriptDirectory.dir = os.path.join(current_app.root_path, 'core', 'plugins', 'alembic') alembic.command.ScriptDirectory = PluginScriptDirectory for plugin in plugins: if not os.path.exists(plugin.alembic_versions_path): print cformat( "%{cyan}skipping plugin '{}' (no migrations folder)" ).format(plugin.name) continue print cformat("%{cyan!}executing command for plugin '{}'").format( plugin.name) with plugin.plugin_context(): func(*args, **kwargs)
def main(): models = { model: make_query(model).count() for model in StoredFileMixin.__subclasses__() } models = {model: total for model, total in models.iteritems() if total} labels = { model: cformat( 'Processing %{blue!}{}%{reset} (%{cyan}{}%{reset} rows)').format( model.__name__, total) for model, total in models.iteritems() } max_length = max(len(x) for x in labels.itervalues()) labels = { model: label.ljust(max_length) for model, label in labels.iteritems() } for model, total in sorted(models.items(), key=itemgetter(1)): with click.progressbar(query_chunked(model, 100), length=total, label=labels[model], show_percent=True, show_pos=True) as objects: for obj in objects: try: with obj.open() as f: checksum = get_file_md5(f) except Exception as exc: click.echo( cformat( '\n%{red!}Could not open %{reset}%{yellow}{}%{red!}: %{reset}%{yellow!}{}' ).format(obj, exc)) else: obj.md5 = checksum
def _print_schedule(self, deleted): table_data = [['Name', 'Schedule']] for entry in sorted(self.app.conf['beat_schedule'].itervalues(), key=itemgetter('task')): table_data.append([cformat('%{yellow!}{}%{reset}').format(entry['task']), cformat('%{green}{!r}%{reset}').format(entry['schedule'])]) for task_name in sorted(deleted): table_data.append([cformat('%{yellow}{}%{reset}').format(task_name), cformat('%{red!}Disabled%{reset}')]) print AsciiTable(table_data, cformat('%{white!}Periodic Tasks%{reset}')).table
def search(substring, include_deleted, include_pending, include_external, include_system, **criteria): """Searches users matching some criteria""" assert set(criteria.viewkeys()) == { 'first_name', 'last_name', 'email', 'affiliation' } criteria = {k: v for k, v in criteria.viewitems() if v is not None} res = search_users(exact=(not substring), include_deleted=include_deleted, include_pending=include_pending, external=include_external, allow_system_user=include_system, **criteria) if not res: print(cformat('%{yellow}No results found')) return elif len(res) > 100: click.confirm('{} results found. Show them anyway?'.format(len(res)), abort=True) users = sorted((u for u in res if isinstance(u, User)), key=lambda x: (x.first_name.lower(), x.last_name.lower(), x.email)) externals = sorted( (ii for ii in res if isinstance(ii, IdentityInfo)), key=lambda x: (_safe_lower(x.data.get('first_name')), _safe_lower(x.data.get('last_name')), _safe_lower(x.data['email']))) if users: table_data = [[ 'ID', 'First Name', 'Last Name', 'Email', 'Affiliation' ]] for user in users: table_data.append([ unicode(user.id), user.first_name, user.last_name, user.email, user.affiliation ]) table = AsciiTable(table_data, cformat('%{white!}Users%{reset}')) table.justify_columns[0] = 'right' print(table.table) if externals: if users: print() table_data = [[ 'First Name', 'Last Name', 'Email', 'Affiliation', 'Source', 'Identifier' ]] for ii in externals: data = ii.data table_data.append([ data.get('first_name', ''), data.get('last_name', ''), data['email'], data.get('affiliation', '-'), ii.provider.name, ii.identifier ]) table = AsciiTable(table_data, cformat('%{white!}Externals%{reset}')) print(table.table)
def _copy(src, dst, force=False): if not force and os.path.exists(dst): _echo( cformat( '%{yellow!}{}%{reset}%{yellow} already exists; not copying %{yellow!}{}' ).format(dst, src)) return _echo( cformat('%{green}Copying %{green!}{}%{reset}%{green} -> %{green!}{}'). format(src, dst)) shutil.copy(src, dst)
def print_result(self, slow=float('inf'), veryslow=float('inf')): duration = float(self) if duration == float('-inf'): print cformat('%{blue!}skipped') elif duration == float('inf'): print cformat('%{red}running') elif duration >= veryslow: print cformat('%{red!}{}').format(self) elif duration >= slow: print cformat('%{yellow!}{}').format(self) else: print cformat('%{green!}{}').format(self)
def _add_to_context(namespace, info, element, name=None, doc=None, color='green'): if not name: name = element.__name__ namespace[name] = element if doc: info.append( cformat('+ %%{%s}{}%%{white!} ({})' % color).format(name, doc)) else: info.append(cformat('+ %%{%s}{}' % color).format(name))
def grant_admin(user_id): """Grants administration rights to a given user""" user = User.get(user_id) if user is None: print(cformat("%{red}This user does not exist")) return _print_user_info(user) if user.is_admin: print(cformat("%{yellow}This user already has administration rights")) return if click.confirm( cformat("%{yellow}Grant administration rights to this user?")): user.is_admin = True db.session.commit() print(cformat("%{green}Administration rights granted successfully"))
def _add_to_context_multi(namespace, info, elements, names=None, doc=None, color='green'): if not names: names = [x.__name__ for x in elements] for name, element in zip(names, elements): namespace[name] = element if doc: info.append( cformat('+ %%{white!}{}:%%{reset} %%{%s}{}' % color).format( doc, ', '.join(names))) else: info.append(cformat('+ %%{%s}{}' % color).format(', '.join(names)))
def revoke_admin(user_id): """Revokes administration rights from a given user""" user = User.get(user_id) if user is None: print(cformat("%{red}This user does not exist")) return _print_user_info(user) if not user.is_admin: print( cformat("%{yellow}This user does not have administration rights")) return if click.confirm( cformat("%{yellow}Revoke administration rights from this user?")): user.is_admin = False db.session.commit() print(cformat("%{green}Administration rights revoked successfully"))
def check_format_strings(): """Check whether format strings match. This helps finding cases where e.g. the original string uses ``{error}`` but the translation uses ``{erro}``, resulting in errors when using the translated string. """ root_path = os.path.join(current_app.root_path, 'translations') paths = set() for root, dirs, files in os.walk(root_path): for file in files: if file.endswith('.po'): paths.add(os.path.join(root, file)) all_valid = True for path in paths: invalid = _get_invalid_po_format_strings(path) if invalid: all_valid = False click.echo('Found invalid format strings in {}'.format(os.path.relpath(path, root_path))) for item in invalid: click.echo(cformat('%{yellow}{}%{reset} | %{yellow!}{}%{reset}\n%{red}{}%{reset} != %{red!}{}%{reset}') .format(item['orig'], item['trans'], list(item['orig_placeholders']), list(item['trans_placeholders']))) click.echo() sys.exit(0 if all_valid else 1)
def _link(src, dst): _echo( cformat( '%{cyan}Linking %{cyan!}{}%{reset}%{cyan} -> %{cyan!}{}').format( dst, src)) if os.path.exists(dst) or os.path.islink(dst): os.unlink(dst) os.symlink(src, dst)
def main(ci): import_all_models() has_missing = has_updates = False for cls, rels in sorted(_find_backrefs().iteritems(), key=lambda x: x[0].__name__): path = _get_source_file(cls) with open(path, 'r') as f: source = [line.rstrip('\n') for line in f] new_source = [] in_class = in_backrefs = backrefs_written = False for i, line in enumerate(source): if in_backrefs: if not backrefs_written: _write_backrefs(rels, new_source) backrefs_written = True if not line.startswith(' # - '): in_backrefs = False else: continue elif in_class: if line == ' # relationship backrefs:': in_backrefs = True elif line and not line.startswith(' ' * 4): # end of the indented class block in_class = False else: if line.startswith('class {}('.format(cls.__name__)): in_class = True new_source.append(line) if in_backrefs and not backrefs_written: _write_backrefs(rels, new_source) if not backrefs_written: print cformat( '%{yellow}Class {} has no comment for backref information' ).format(cls.__name__) has_missing = True if source != new_source: print cformat( '%{green!}Updating backref info for {} in {}').format( cls.__name__, path) has_updates = True with open(path, 'w') as f: f.writelines(line + '\n' for line in new_source) sys.exit(1 if (has_missing or (ci and has_updates)) else 0)
def create(grant_admin): """Creates a new user""" user_type = 'user' if not grant_admin else 'admin' while True: email = prompt_email() if email is None: return email = email.lower() if not User.find(User.all_emails.contains(email), ~User.is_deleted, ~User.is_pending).count(): break print(cformat('%{red}Email already exists')) first_name = click.prompt("First name").strip() last_name = click.prompt("Last name").strip() affiliation = click.prompt("Affiliation", '').strip() print() while True: username = click.prompt("Enter username").lower().strip() if not Identity.find(provider='fossir', identifier=username).count(): break print(cformat('%{red}Username already exists')) password = prompt_pass() if password is None: return identity = Identity(provider='fossir', identifier=username, password=password) user = create_user( email, { 'first_name': to_unicode(first_name), 'last_name': to_unicode(last_name), 'affiliation': to_unicode(affiliation) }, identity) user.is_admin = grant_admin _print_user_info(user) if click.confirm(cformat("%{yellow}Create the new {}?").format(user_type), default=True): db.session.add(user) db.session.commit() print( cformat("%{green}New {} created successfully with ID: %{green!}{}" ).format(user_type, user.id))
def list_plugins(): """Lists the available fossir plugins.""" table_data = [['Name', 'Title']] for ep in sorted(iter_entry_points('fossir.plugins'), key=attrgetter('name')): plugin = ep.load() table_data.append([ep.name, plugin.title]) table = AsciiTable(table_data, cformat('%{white!}Available Plugins%{reset}')) click.echo(table.table)
def _make_shell_context(): context = {} info = [cformat('%{white!}Available objects')] add_to_context = partial(_add_to_context, context, info) add_to_context_multi = partial(_add_to_context_multi, context, info) add_to_context_smart = partial(_add_to_context_smart, context, info) # Common stdlib modules info.append(cformat('*** %{magenta!}stdlib%{reset} ***')) DATETIME_ATTRS = ('date', 'time', 'datetime', 'timedelta') ORM_ATTRS = ('joinedload', 'defaultload', 'contains_eager', 'lazyload', 'noload', 'subqueryload', 'undefer', 'undefer_group', 'load_only') add_to_context_multi([getattr(datetime, attr) for attr in DATETIME_ATTRS] + [getattr(sqlalchemy.orm, attr) for attr in ORM_ATTRS] + [itertools, re, sys, os], color='yellow') # Models info.append(cformat('*** %{magenta!}Models%{reset} ***')) models = [ cls for name, cls in sorted(db.Model._decl_class_registry.items(), key=itemgetter(0)) if hasattr(cls, '__table__') ] add_to_context_smart(models) # Tasks info.append(cformat('*** %{magenta!}Tasks%{reset} ***')) tasks = [ task for task in sorted(celery.tasks.values()) if not task.name.startswith('celery.') ] add_to_context_smart(tasks, get_name=lambda x: x.name.replace('.', '_'), color='blue!') # Plugins info.append(cformat('*** %{magenta!}Plugins%{reset} ***')) plugins = [ type(plugin) for plugin in sorted(plugin_engine.get_active_plugins().values(), key=attrgetter('name')) ] add_to_context_multi(plugins, color='yellow!') # Utils info.append(cformat('*** %{magenta!}Misc%{reset} ***')) add_to_context(celery, 'celery', doc='celery app', color='blue!') add_to_context(db, 'db', doc='sqlalchemy db interface', color='cyan!') add_to_context(now_utc, 'now_utc', doc='get current utc time', color='cyan!') add_to_context(config, 'config', doc='fossir config') add_to_context(current_app, 'app', doc='flask app') add_to_context(lambda *a, **kw: server_to_utc(datetime.datetime(*a, **kw)), 'dt', doc='like datetime() but converted from localtime to utc') add_to_context(Event.get, 'EE', doc='get event by id') # Stuff from plugins signals.plugin.shell_context.send( add_to_context=add_to_context, add_to_context_multi=add_to_context_multi) return context, info
def create_all_tables(db, verbose=False, add_initial_data=True): """Create all tables and required initial objects""" from fossir.modules.categories import Category from fossir.modules.designer import TemplateType from fossir.modules.designer.models.templates import DesignerTemplate from fossir.modules.oauth.models.applications import OAuthApplication, SystemAppType from fossir.modules.users import User if verbose: print cformat('%{green}Creating tables') db.create_all() if add_initial_data: if verbose: print cformat('%{green}Creating system user') db.session.add( User(id=0, is_system=True, first_name='fossir', last_name='System')) if verbose: print cformat('%{green}Creating root category') cat = Category(id=0, title='Home', protection_mode=ProtectionMode.public) db.session.add(cat) db.session.flush() if verbose: print cformat( '%{green}Creating default ticket template for root category ') dt = DesignerTemplate(category_id=0, title='Default ticket', type=TemplateType.badge, data=DEFAULT_TEMPLATE_DATA, is_system_template=True) cat.default_ticket_template = dt db.session.add(dt) if verbose: print cformat('%{green}Creating system oauth apps') for sat in SystemAppType: if sat != SystemAppType.none: db.session.add( OAuthApplication(system_app_type=sat, **sat.default_data)) db.session.commit()
def _check_directories(self, dev=False): dirs = ['archive', 'assets', 'cache', 'log', 'tmp'] if not dev: dirs += ['etc', 'web'] _echo('fossir will use the following directories') has_existing = False for name in dirs: path = os.path.join(self.data_root_path, name) exists_suffix = '' if os.path.exists(path): has_existing = True exists_suffix = cformat(' %{yellow!}*%{reset}') else: self._missing_dirs.add(path) _echo(cformat(' %{blue!}{}%{reset}').format(path) + exists_suffix) if has_existing: _warn( 'The directories marked with a * already exist. We strongly recommend installing fossir in a new ' 'directory that contains nothing but the Python virtualenv. If you are upgrading from fossir v1.2, ' 'please move its data to a different location.') _prompt_abort()
def _print_occurrences(user, occurrences, _defaults={}, _overrides={}): if not _defaults or not _overrides: _defaults.update({ RepeatFrequency.WEEK: rb_settings.get('notification_before_days_weekly'), RepeatFrequency.MONTH: rb_settings.get('notification_before_days_monthly'), RepeatFrequency.NEVER: rb_settings.get('notification_before_days'), RepeatFrequency.DAY: rb_settings.get('notification_before_days') }) _overrides.update({ RepeatFrequency.WEEK: lambda r: r.notification_before_days_weekly, RepeatFrequency.MONTH: lambda r: r.notification_before_days_monthly, RepeatFrequency.NEVER: lambda r: r.notification_before_days, RepeatFrequency.DAY: lambda r: r.notification_before_days }) print cformat('%{grey!}*** {} ({}) ***').format(user.full_name, user.email) for occ in occurrences: default = _defaults[occ.reservation.repeat_frequency] override = _overrides[occ.reservation.repeat_frequency]( occ.reservation.room) days = default if override is None else override days_until = (occ.start_dt.date() - date.today()).days print cformat( ' * %{yellow}{}%{reset} %{green}{:5}%{reset} {} {} {} \t %{blue!}{}%{reset} {} ({})' ).format( occ.start_dt.date(), occ.reservation.repeat_frequency.name, days, default if override is not None and override != default else ' ', days_until, occ.reservation.id, occ.reservation.room.full_name, occ.reservation.room.id)
def _update_header(file_path, year, substring, regex, data): with open(file_path, 'r') as file_read: content = orig_content = file_read.read() if not content.strip(): return for match in regex.finditer(content): if substring in match.group(): content = content[:match.start()] + gen_header( data, year) + content[match.end():] if content != orig_content: print( cformat('%{green}Updating header of %{green!}{}').format( os.path.relpath(file_path))) with open(file_path, 'w') as file_write: file_write.write(content)
def main(): if '-h' in sys.argv or '--help' in sys.argv: print(USAGE) sys.exit(1) year, path, file_ = _process_args(sys.argv[1:]) if path is not None: print( cformat( "Updating headers to the year %{yellow!}{year}%{reset} for all the files in " "%{yellow!}{path}%{reset}...").format(year=year, path=path)) for root, _, filenames in os.walk(path): for filename in filenames: update_header(os.path.join(root, filename), year) elif file_ is not None: print( cformat( "Updating headers to the year %{yellow!}{year}%{reset} for the file " "%{yellow!}{file}%{reset}...").format(year=year, file=file_)) update_header(file_, year) else: print( cformat( "Updating headers to the year %{yellow!}{year}%{reset} for all " "git-tracked files...").format(year=year)) try: for path in check_output(['git', 'ls-files']).splitlines(): update_header(os.path.abspath(path), year) except CalledProcessError: print(cformat( '%{red!}[ERROR] you must be within a git repository to run this script.' ), file=sys.stderr) print(USAGE) sys.exit(1)
def _get_dirs(target_dir): if not os.path.isdir(target_dir): _echo( cformat('%{red}Directory not found:%{red!} {}').format(target_dir)) sys.exit(1) return get_root_path('fossir'), os.path.abspath(target_dir)
def _setup(self, dev=False): storage_backends = { 'default': 'fs:' + os.path.join(self.data_root_path, 'archive') } if self.old_archive_dir: storage_backends['legacy'] = 'fs-readonly:' + self.old_archive_dir config_link_path = os.path.expanduser('~/.fossir.conf') if not dev: create_config_link = _confirm( 'Create symlink?', default=True, help='By creating a symlink to fossir.conf in {}, you can run ' 'fossir without having to set the fossir_CONFIG ' 'environment variable'.format(config_link_path)) else: create_config_link = False config_data = [ b'# General settings', b'SQLALCHEMY_DATABASE_URI = {!r}'.format( self.db_uri.encode('utf-8')), b'SECRET_KEY = {!r}'.format( os.urandom(32)), b'BASE_URL = {!r}'.format( self.fossir_url.encode('utf-8')), b'CELERY_BROKER = {!r}'.format( self.redis_uri_celery.encode('utf-8')), b'REDIS_CACHE_URL = {!r}'.format( self.redis_uri_cache.encode('utf-8')), b"CACHE_BACKEND = 'redis'", b'DEFAULT_TIMEZONE = {!r}'.format( self.default_timezone.encode('utf-8')), b'DEFAULT_LOCALE = {!r}'.format( self.default_locale.encode('utf-8')), b'ENABLE_ROOMBOOKING = {!r}'.format(self.rb_active), b'CACHE_DIR = {!r}'.format( os.path.join(self.data_root_path, 'cache').encode('utf-8')), b'TEMP_DIR = {!r}'.format( os.path.join(self.data_root_path, 'tmp').encode('utf-8')), b'LOG_DIR = {!r}'.format( os.path.join(self.data_root_path, 'log').encode('utf-8')), b'ASSETS_DIR = {!r}'.format( os.path.join(self.data_root_path, 'assets').encode('utf-8')), b'STORAGE_BACKENDS = {!r}'.format({ k.encode('utf-8'): v.encode('utf-8') for k, v in storage_backends.iteritems() }), b"ATTACHMENT_STORAGE = 'default'", b'ROUTE_OLD_URLS = True' if self.old_archive_dir else None, b'', b'# Email settings', b'SMTP_SERVER = {!r}'.format( (self.smtp_host.encode('utf-8'), self.smtp_port)), b'SMTP_USE_TLS = {!r}'.format( bool(self.smtp_user and self.smtp_password)), b'SMTP_LOGIN = {!r}'.format(self.smtp_user.encode('utf-8')), b'SMTP_PASSWORD = {!r}'.format(self.smtp_password.encode('utf-8')), b'SUPPORT_EMAIL = {!r}'.format(self.admin_email.encode('utf-8')), b'PUBLIC_SUPPORT_EMAIL = {!r}'.format( self.contact_email.encode('utf-8')), b'NO_REPLY_EMAIL = {!r}'.format(self.noreply_email.encode('utf-8')) ] if dev: config_data += [ b'', b'# Development options', b'DB_LOG = True', b'DEBUG = True', b'SMTP_USE_CELERY = False' ] config = b'\n'.join(x for x in config_data if x is not None) if dev: if not os.path.exists(self.data_root_path): os.mkdir(self.data_root_path) _echo() for path in self._missing_dirs: _echo( cformat('%{magenta}Creating %{magenta!}{}%{reset}%{magenta}'). format(path)) os.mkdir(path) _echo( cformat( '%{magenta}Creating %{magenta!}{}%{reset}%{magenta}').format( self.config_path)) with open(self.config_path, 'wb') as f: f.write(config + b'\n') package_root = get_root_path('fossir') _copy( os.path.normpath(os.path.join(package_root, 'logging.yaml.sample')), os.path.join(self.config_dir_path, 'logging.yaml')) if not dev: _link(os.path.join(package_root, 'htdocs'), os.path.join(self.data_root_path, 'web', 'htdocs')) _copy(os.path.join(package_root, 'web', 'fossir.wsgi'), os.path.join(self.data_root_path, 'web', 'fossir.wsgi'), force=True) if create_config_link: _link(self.config_path, config_link_path) _echo() _echo(cformat('%{green}fossir has been configured successfully!')) if not dev and not create_config_link: _echo( cformat( 'Run %{green!}export fossir_CONFIG={}%{reset} to use your config file' ).format(self.config_path)) if self.old_archive_dir: _echo( cformat( 'Check %{green!}https://git.io/vHP6o%{reset} for a guide on how to ' 'import data from fossir v1.2')) else: _echo( cformat( 'You can now run %{green!}fossir db prepare%{reset} to initialize your fossir database' ))
def celery_cmd(args): # remove the celery shell command next(funcs for group, funcs, _ in command_classes if group == 'Main').remove('shell') del CeleryCommand.commands['shell'] if args and args[0] == 'flower': # Somehow flower hangs when executing it using CeleryCommand() so we simply exec it directly. # It doesn't really need the celery config anyway (besides the broker url) try: import flower except ImportError: print cformat('%{red!}Flower is not installed') sys.exit(1) app = OAuthApplication.find_one(system_app_type=SystemAppType.flower) if not app.redirect_uris: print cformat( '%{yellow!}Authentication will fail unless you configure the redirect url for the {} OAuth ' 'application in the administration area.').format(app.name) print cformat( '%{green!}Only fossir admins will have access to flower.') print cformat( '%{yellow}Note that revoking admin privileges will not revoke Flower access.' ) print cformat('%{yellow}To force re-authentication, restart Flower.') auth_args = [ '--auth=^fossir Admin$', '--auth_provider=fossir.core.celery.flower.FlowerAuthHandler' ] auth_env = { 'fossir_FLOWER_CLIENT_ID': app.client_id, 'fossir_FLOWER_CLIENT_SECRET': app.client_secret, 'fossir_FLOWER_AUTHORIZE_URL': url_for('oauth.oauth_authorize', _external=True), 'fossir_FLOWER_TOKEN_URL': url_for('oauth.oauth_token', _external=True), 'fossir_FLOWER_USER_URL': url_for('users.authenticated_user', _external=True) } args = ['celery', '-b', config.CELERY_BROKER] + args + auth_args env = dict(os.environ, **auth_env) os.execvpe('celery', args, env) elif args and args[0] == 'shell': print cformat('%{red!}Please use `fossir shell`.') sys.exit(1) else: CeleryCommand(celery).execute_from_commandline(['fossir celery'] + args)
def run(self, name, **kwargs): if unlock_task(name): print cformat('%{green!}Task {} unlocked').format(name) else: print cformat('%{yellow}Task {} is not locked').format(name)
def _safe_downgrade(*args, **kwargs): func = kwargs.pop('_func') print cformat('%{yellow!}*** DANGER') print cformat( '%{yellow!}***%{reset} ' '%{red!}This operation may %{yellow!}PERMANENTLY ERASE %{red!}some data!%{reset}' ) if current_app.debug: skip_confirm = os.environ.get('fossir_ALWAYS_DOWNGRADE', '').lower() in ('1', 'yes') print cformat( '%{yellow!}***%{reset} ' "%{green!}Debug mode is active, so you probably won't destroy valuable data" ) else: skip_confirm = False print cformat( '%{yellow!}***%{reset} ' "%{red!}Debug mode is NOT ACTIVE, so make sure you are on the right machine!" ) if not skip_confirm and raw_input( cformat( '%{yellow!}***%{reset} ' 'To confirm this, enter %{yellow!}YES%{reset}: ')) != 'YES': print cformat('%{green}Aborted%{reset}') sys.exit(1) else: return func(*args, **kwargs)
def _process_format(fmt, _re=re.compile(r'<([^>]+)>')): fmt = _re.sub(r'%{reset}%{cyan}\1%{reset}%{blue!}', fmt) return cformat('- %{blue!}' + fmt)
def _load_users(self, data): if not data['users']: return missing = {} for uuid, userdata in data['users'].iteritems(): if userdata is None: self.user_map[uuid] = self.system_user_id continue user = (User.query.filter( User.all_emails.contains(db.func.any(userdata['all_emails'])), ~User.is_deleted).one_or_none()) if user is None: missing[uuid] = userdata else: self.user_map[uuid] = user.id if missing: click.secho( 'The following users from the import data could not be mapped to existing users:', fg='yellow') table_data = [['First Name', 'Last Name', 'Email', 'Affiliation']] for userdata in sorted(missing.itervalues(), key=itemgetter('first_name', 'last_name', 'email')): table_data.append([ userdata['first_name'], userdata['last_name'], userdata['email'], userdata['affiliation'] ]) table = AsciiTable(table_data) click.echo(table.table) if self.create_users is None: click.echo('Do you want to create these users now?') click.echo( 'If you choose to not create them, the behavior depends on where the user would be used:' ) click.echo( '- If the user is not required, it will be omitted.') click.echo( '- If a user is required but using the system user will not cause any problems or look ' 'weird, the system user will be used.') click.echo( '- In case neither is possible, e.g. in abstract reviews or ACLs, these objects will ' 'be skipped altogether!') create_users = click.confirm('Create the missing users?', default=True) else: create_users = self.create_users if create_users: click.secho('Creating missing users', fg='magenta') for uuid, userdata in missing.iteritems(): user = User(first_name=userdata['first_name'], last_name=userdata['last_name'], email=userdata['email'], secondary_emails=set(userdata['all_emails']) - {userdata['email']}, address=userdata['address'], phone=userdata['phone'], affiliation=userdata['affiliation'], title=userdata['title'], is_pending=True) db.session.add(user) db.session.flush() self.user_map[uuid] = user.id if self.verbose: click.echo( cformat("- %{cyan}User%{blue!} '{}' ({})").format( user.full_name, user.email)) else: click.secho('Skipping missing users', fg='magenta')