Example #1
0
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)
Example #3
0
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
Example #4
0
 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
Example #5
0
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)
Example #6
0
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)
Example #8
0
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))
Example #9
0
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"))
Example #10
0
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)))
Example #11
0
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"))
Example #12
0
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)
Example #13
0
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)
Example #15
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))
Example #16
0
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)
Example #17
0
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
Example #18
0
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()
Example #19
0
    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()
Example #20
0
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)
Example #21
0
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)
Example #22
0
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)
Example #23
0
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)
Example #24
0
    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'
                ))
Example #25
0
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)
Example #26
0
 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)
Example #28
0
 def _process_format(fmt, _re=re.compile(r'<([^>]+)>')):
     fmt = _re.sub(r'%{reset}%{cyan}\1%{reset}%{blue!}', fmt)
     return cformat('- %{blue!}' + fmt)
Example #29
0
 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')