Example #1
0
def create_test_job(manager_id, user_email, project_url):
    """Creates a test job for a given manager."""

    from pillar.api.utils import dumps, str2id

    manager_id = str2id(manager_id)
    authentication.force_cli_user()

    # Find user
    users_coll = current_app.db()['users']
    user = users_coll.find_one({'email': user_email}, projection={'_id': 1})
    if not user:
        raise ValueError('User with email %r not found' % user_email)

    # Find project
    projs_coll = current_app.db()['projects']
    proj = projs_coll.find_one({'url': project_url}, projection={'_id': 1})
    if not proj:
        log.error('Unable to find project url=%s', project_url)
        return 1

    # Create the job
    job = flamenco.current_flamenco.job_manager.api_create_job(
        'CLI test job', 'Test job created from the server CLI', 'sleep', {
            'frames': '1-30, 40-44',
            'chunk_size': 13,
            'time_in_seconds': 3,
        }, proj['_id'], user['_id'], manager_id)

    log.info('Job created:\n%s', dumps(job, indent=4))
Example #2
0
File: cli.py Project: jonike/dillo
def process_posts(community_name):
    """Manually trigger pre-update hooks."""
    from flask import g
    from pillar.auth import UserClass
    from dillo.api.posts.hooks import process_picture_oembed, before_replacing_post
    from dillo.setup import _get_project
    project = _get_project(community_name)

    nodes_collection = current_app.db()['nodes']
    user_collection = current_app.db()['users']
    nc = nodes_collection.find({
        'node_type': 'dillo_post',
        'properties.status': 'published',
        'project': project['_id'],
    })

    for n in nc:
        # Log in as doc user
        user_doc = user_collection.find_one({'_id': n['user']})
        u = UserClass.construct(user_doc['_id'], user_doc)
        g.current_user = u

        n_id = n['_id']
        print(f'Processing node {n_id}')
        process_picture_oembed(n, n)
        before_replacing_post(n, n)
        nodes_collection.find_one_and_replace({'_id': n_id}, n)
Example #3
0
def create_test_job(manager_id, user_email, project_url):
    """Creates a test job for a given manager."""

    from pillar.api.utils import dumps, str2id

    manager_id = str2id(manager_id)
    authentication.force_cli_user()

    # Find user
    users_coll = current_app.db()['users']
    user = users_coll.find_one({'email': user_email}, projection={'_id': 1})
    if not user:
        raise ValueError('User with email %r not found' % user_email)

    # Find project
    projs_coll = current_app.db()['projects']
    proj = projs_coll.find_one({'url': project_url},
                               projection={'_id': 1})
    if not proj:
        log.error('Unable to find project url=%s', project_url)
        return 1

    # Create the job
    job = flamenco.current_flamenco.job_manager.api_create_job(
        'CLI test job',
        'Test job created from the server CLI',
        'sleep',
        {
            'frames': '1-30, 40-44',
            'chunk_size': 13,
            'time_in_seconds': 3,
        },
        proj['_id'], user['_id'], manager_id)

    log.info('Job created:\n%s', dumps(job, indent=4))
 def select(self, sql, campos=None, sel='fetchone'):
     """Seleciona Registros da Tabela."""
     if sel == 'fetchone':
         model = None
         items = current_app.db().select(sql, campos, sel)
         if items:
             model = self.__class__(items)
     elif sel == 'fetchall':
         model = current_app.db().select(sql, campos, sel)
         model = [self.__class__(i) for i in model]
     return model
Example #5
0
def patch_post(node_id, patch):
    assert_is_valid_patch(node_id, patch)
    user_id = authentication.current_user_id()

    if patch['op'] in COMMENT_VOTING_OPS:
        nodes_coll = current_app.db()['nodes']
        node = nodes_coll.find_one({'_id': node_id})

        old_rating = rating_difference(node)
        result, node = vote_comment(user_id, node_id, patch)
        new_rating = rating_difference(node)

        # Update the user karma based on the rating differences.
        karma_increase = (new_rating - old_rating) * POST_VOTE_WEIGHT
        if karma_increase != 0:
            node_user_id = nodes_coll.find_one({'_id': node_id},
                                               projection={
                                                   'user': 1,
                                               })['user']

            users_collection = current_app.db()['users']
            db_fieldname = f'extension_props_public.{EXTENSION_NAME}.karma'

            users_collection.find_one_and_update(
                {'_id': node_user_id},
                {'$inc': {
                    db_fieldname: karma_increase
                }},
                {db_fieldname: 1},
            )

        # Fetch the full node for updating hotness and reindexing
        # TODO (can be improved by making a partial update)
        node = nodes_coll.find_one({'_id': node['_id']})
        update_hot(node)
        nodes_coll.update_one(
            {'_id': node['_id']},
            {'$set': {
                'properties.hot': node['properties']['hot']
            }})

        algolia_index_post_save(node)
    else:
        return abort(403)

    return jsonify({
        '_status': 'OK',
        'result': result,
        'properties': node['properties']
    })
Example #6
0
def update_download_count(post_id):
    """Update download count for the Post.

    This function is called from dillo.web.posts.routes.download_file.
    """

    current_app.db('nodes').update_one({'_id': ObjectId(post_id)}, {
        '$inc': {
            'properties.downloads_total': 1,
            'properties.downloads_latest': 1
        }
    })

    log.debug('Updated download count for post %s' % post_id)
    return jsonify({'status': 'OK'})
Example #7
0
def unfollow(project_id: str):
    """Remove a community from followed_communities of current_user."""
    # Ensure that the community requested exists
    community = get_community(project_id)

    users_coll = current_app.db('users')

    # Fetch user
    user = users_coll.find_one(current_user.user_id)
    # Look for project in in extension_props_public.dillo.followed_communities
    followed_communities = user['extension_props_public'][EXTENSION_NAME]. \
        get('followed_communities', [])

    # Check if the user already does not follow the community
    if followed_communities and community['_id'] not in followed_communities:
        log.debug('User does not follow community %s' % community['url'])
        return abort(403)

    followed_communities = [
        c for c in followed_communities if c != community['_id']
    ]

    followed_communities_key = f'extension_props_public.{EXTENSION_NAME}.followed_communities'
    users_coll.update_one(
        {'_id': current_user.user_id},
        {'$set': {
            followed_communities_key: followed_communities
        }})

    log.debug('Community %s successfully unfollowed' % community['name'])
    return jsonify({
        '_status': 'OK',
        'message': f"Unfollowed {community['name']}"
    })
Example #8
0
def get_file_url(file_id: ObjectId, variation='') -> str:
    """Return the URL of a file in storage.

    Note that this function is cached, see setup_app().

    :param file_id: the ID of the file
    :param variation: if non-empty, indicates the variation of of the file
        to return the URL for; if empty, returns the URL of the original.

    :return: the URL, or an empty string if the file/variation does not exist.
    """

    file_coll = current_app.db('files')
    db_file = file_coll.find_one({'_id': file_id})
    if not db_file:
        return ''

    ensure_valid_link(db_file)

    if variation:
        variations = file_doc.get('variations', ())
        for file_var in variations:
            if file_var['size'] == variation:
                return file_var['link']
        return ''

    return db_file['link']
Example #9
0
def create_manager(owner_email, name, description):
    """Creates a Flamenco manager with service account.

    :returns: tuple (mngr_doc, account, token)
    """

    from pymongo.cursor import Cursor

    # Find the owner, to add it to the owner group afterward.
    possible_owners: Cursor = current_app.db('users').find(
        {'email': owner_email}, {
            '_id': 1,
            'full_name': 1
        })
    owner_count = possible_owners.count()
    if owner_count == 0:
        raise ValueError(f'No user found with email address {owner_email}; '
                         'cannot assign ownership of Manager')
    if owner_count > 1:
        raise ValueError(
            f'Multiple users ({owner_count}) found with email address {owner_email}; '
            'cannot assign ownership of Manager')
    owner = possible_owners[0]
    owner_id = owner['_id']

    account, mngr_doc, token = current_flamenco.manager_manager.create_new_manager(
        name, description, owner_id)

    return mngr_doc, account, token
Example #10
0
def create_manager(owner_email, name, description):
    """Creates a Flamenco manager with service account.

    :returns: tuple (mngr_doc, account, token)
    """

    from pymongo.cursor import Cursor

    # Find the owner, to add it to the owner group afterward.
    possible_owners: Cursor = current_app.db('users').find(
        {'email': owner_email},
        {'_id': 1, 'full_name': 1})
    owner_count = possible_owners.count()
    if owner_count == 0:
        raise ValueError(f'No user found with email address {owner_email}; '
                         'cannot assign ownership of Manager')
    if owner_count > 1:
        raise ValueError(f'Multiple users ({owner_count}) found with email address {owner_email}; '
                         'cannot assign ownership of Manager')
    owner = possible_owners[0]
    owner_id = owner['_id']

    account, mngr_doc, token = current_flamenco.manager_manager.create_new_manager(
        name, description, owner_id)

    return mngr_doc, account, token
Example #11
0
def generate_shortcode(project_id, node_type):
    """Generates and returns a new shortcode.

    :param project_id: project ID
    :type project_id: bson.ObjectId
    :param node_type: the type, for now 'dillo_post', but can be extended.
    :type node_type: unicode
    """

    assert isinstance(project_id, ObjectId)

    db = current_app.db()
    db_fieldname = 'extension_props.dillo.last_used_shortcodes.%s' % node_type

    log.debug('Incrementing project %s shortcode for type %r',
              project_id, node_type)

    new_proj = db['projects'].find_one_and_update(
        {'_id': project_id},
        {'$inc': {db_fieldname: 1}},
        {db_fieldname: 1},
        return_document=pymongo.ReturnDocument.AFTER,
    )

    shortcode = new_proj['extension_props']['dillo']['last_used_shortcodes'][node_type]
    return encode_id(shortcode)
Example #12
0
def rebuild_karma():
    """Re-calculate users karma

    It also initialize the ['extension_props_public']['karma'] if needed.
    """
    db = current_app.db()
    users_collection = db['users'].find({'_deleted': {'$ne': True}})
    db_fieldname = f'extension_props_public.{EXTENSION_NAME}.karma'

    for user in users_collection:
        posts_collection = db['nodes'].find({
            'node_type': 'dillo_post',
            'user': user['_id'],
        })

        karma = 0
        for post in posts_collection:
            karma += rating_difference(post) * POST_VOTE_WEIGHT

        db['users'].find_one_and_update(
            {'_id': user['_id']},
            {'$set': {
                db_fieldname: karma
            }},
            {db_fieldname: 1},
        )
Example #13
0
def assign_to_user_main(user_doc: dict):
    """Make every user create part of the user_main group."""

    groups_coll = current_app.db().groups
    group_dillo_user_main = groups_coll.find_one({'name': 'dillo_user_main'})
    add_user_to_group(user_id=user_doc['_id'],
                      group_id=group_dillo_user_main['_id'])
Example #14
0
def follow(project_id: str):
    """Add the community to followed_communities."""
    # Ensure that the community requested exists
    community = get_community(project_id)

    users_coll = current_app.db('users')

    # Fetch user
    user = users_coll.find_one(current_user.user_id)
    # Look for project in in extension_props_public.dillo.followed_communities
    followed_communities = user['extension_props_public'][EXTENSION_NAME].\
        get('followed_communities', [])

    # Check if the user already follows the community
    if followed_communities and community['_id'] in followed_communities:
        log.debug('User already follows community %s' % community['url'])
        return abort(403)

    # Append the followed community to the existing list
    followed_communities.append(community['_id'])

    followed_communities_key = f'extension_props_public.{EXTENSION_NAME}.followed_communities'
    users_coll.update_one(
        {'_id': current_user.user_id},
        {'$set': {
            followed_communities_key: followed_communities
        }})

    return jsonify({
        '_status': 'OK',
        'message': f"Following {community['name']}"
    })
Example #15
0
 def update(self, campo, val):
     """Atualiza os campos da tabela."""
     dic = self.getDict()
     campos = ', '.join(
         map(lambda x: ' = '.join(x),
             zip(
                 filter(
                     lambda x: not (self.__pk__ == x),
                     dic.keys()
                 ),
                 map(lambda x: f"%({x})s",
                     filter(
                         lambda x: not (self.__pk__ == x),
                         dic.keys()
                         )
                     )
                 )
             )
         )
     dic[campo] = val
     return current_app.db().operacao(
         f"UPDATE {self.__table__} "
         f"SET {campos} where {campo} = %({campo})s",
         dic
     )
Example #16
0
def get_community(project_id: str):
    """Fetch a valid community by its string id."""

    # Cast to ObjectId
    project_id = str2id(project_id)

    # Ensure the project exists
    projects_coll = current_app.db('projects')
    community = projects_coll.find_one(
        {
            '_id': project_id,
            '_deleted': {
                '$ne': True
            },
        }, {
            f'extension_props.{EXTENSION_NAME}': 1,
            'name': 1
        })
    if not community:
        log.debug('Project %s does not exist' % project_id)
        return abort(404)

    # Ensure the project is a community (was setup_for_dillo)
    if EXTENSION_NAME not in community['extension_props']:
        log.warning(
            'Project %s is not a setup for Dillo and can not be followed' %
            project_id)
        return abort(403)

    return community
Example #17
0
def _tagged(tag: str):
    """Fetch all public nodes with the given tag.

    This function is cached, see setup_app().
    """
    nodes_coll = current_app.db('nodes')
    agg = nodes_coll.aggregate([
        {'$match': {'properties.tags': tag,
                    '_deleted': {'$ne': True}}},

        # Only get nodes from public projects. This is done after matching the
        # tagged nodes, because most likely nobody else will be able to tag
        # nodes anyway.
        {'$lookup': {
            'from': 'projects',
            'localField': 'project',
            'foreignField': '_id',
            'as': '_project',
        }},
        {'$unwind': '$_project'},
        {'$match': {'_project.is_private': False}},
        {'$addFields': {
            'project._id': '$_project._id',
            'project.name': '$_project.name',
            'project.url': '$_project.url',
        }},

        # Don't return the entire project/file for each node.
        {'$project': {'_project': False}},
        {'$sort': {'_created': -1}}
    ])

    return list(agg)
Example #18
0
def add_communities_filter(pipeline):
    """Given an aggregation pipeline, add a filter for communities."""

    current_user = pillar.auth.get_current_user()

    default_followed_community_ids = current_app.config[
        'DEFAULT_FOLLOWED_COMMUNITY_IDS']
    # Add filter for communities
    if current_user.is_anonymous and default_followed_community_ids:
        pipeline[0]['$match']['project'] = {
            '$in': default_followed_community_ids
        }
    elif current_user.is_authenticated:
        users_coll = current_app.db('users')
        followed_communities_key = f'extension_props_public.{EXTENSION_NAME}.followed_communities'
        # TODO(fsiddi) project into a shorter key instead of followed_communities
        followed = users_coll.find_one(
            {
                '_id': current_user.user_id,
                followed_communities_key: {
                    '$exists': True
                }
            }, {followed_communities_key: 1})
        # If current user is following communities, use them as filter
        if followed:
            fcl = followed['extension_props_public'][EXTENSION_NAME][
                'followed_communities']
            communities = [c for c in fcl]
            pipeline[0]['$match']['project'] = {'$in': communities}
        # Otherwise, try to use default communities
        elif default_followed_community_ids:
            pipeline[0]['$match']['project'] = {
                '$in': default_followed_community_ids
            }
Example #19
0
def user_group_action(user_id: bson.ObjectId, group_id: bson.ObjectId,
                      action: str):
    """Performs a group action (add/remove).

    :param user_id: the user's ObjectID.
    :param group_id: the group's ObjectID.
    :param action: either '$pull' to remove from a group, or '$addToSet' to add to a group.
    """

    from pymongo.results import UpdateResult

    assert isinstance(user_id, bson.ObjectId)
    assert isinstance(group_id, bson.ObjectId)
    assert action in {'$pull', '$addToSet'}

    users_coll = current_app.db('users')
    result: UpdateResult = users_coll.update_one(
        {'_id': user_id},
        {action: {
            'groups': group_id
        }},
    )

    if result.matched_count == 0:
        raise ValueError(
            f'Unable to {action} user {user_id} membership of group {group_id}; '
            f'user not found.')
Example #20
0
 def insert(self):
     """Insere os dados na tabela com os campos adicionados."""
     campos = ", ".join(self.getDict().keys())
     values = ", ".join(map(lambda x: f"%({x})s", self.getDict().keys()))
     return current_app.db().operacao(
         f"INSERT INTO {self.__table__}({campos}) VALUES ({values})",
         self.getDict()
     )
Example #21
0
def _public_project_ids() -> typing.List[bson.ObjectId]:
    """Returns a list of ObjectIDs of public projects.

    Memoized in setup_app().
    """

    proj_coll = current_app.db('projects')
    result = proj_coll.find({'is_private': False}, {'_id': 1})
    return [p['_id'] for p in result]
Example #22
0
def remove_token(token: str):
    """Removes the token from the database."""

    tokens_coll = current_app.db('tokens')
    token_hashed = hash_auth_token(token)

    # TODO: remove matching on hashed tokens once all hashed tokens have expired.
    lookup = {'$or': [{'token': token}, {'token_hashed': token_hashed}]}
    del_res = tokens_coll.delete_many(lookup)
    log.debug('Removed token %r, matched %d documents', token,
              del_res.deleted_count)
Example #23
0
def user_rights_in_project(project_id: ObjectId) -> frozenset:
    """Returns the set of HTTP methods allowed on the given project for the current user."""

    from pillar.api.utils import authorization

    assert isinstance(project_id, ObjectId)

    proj_coll = current_app.db().projects
    proj = proj_coll.find_one({'_id': project_id})

    return frozenset(authorization.compute_allowed_methods('projects', proj))
Example #24
0
def _parent_name(task):
    """Returns 'for shot "shotname"' if the task is attached to the shot."""

    parent = task.get('parent')
    if not parent:
        return ''

    nodes_coll = current_app.db()['nodes']
    shot = nodes_coll.find_one(parent)
    if shot:
        return ' for shot "%s"' % shot['name']

    return ''
Example #25
0
def notification_get_subscriptions(context_object_type, context_object_id,
                                   actor_user_id):
    subscriptions_collection = current_app.db('activities-subscriptions')
    lookup = {
        'user': {
            "$ne": actor_user_id
        },
        'context_object_type': context_object_type,
        'context_object': context_object_id,
        'is_subscribed': True,
    }
    return subscriptions_collection.find(
        lookup), subscriptions_collection.count_documents(lookup)
Example #26
0
def count_blender_sync(query=None) -> int:
    pipeline = [
        # 0 Find all startups.blend that are not deleted
        {
            '$match': {
                '_deleted': {
                    '$ne': 'true'
                },
                'name': 'startup.blend',
            }
        },
        # 1 Group them per project (drops any duplicates)
        {
            '$group': {
                '_id': '$project'
            }
        },
        # 2 Join the project info
        {
            '$lookup': {
                'from': "projects",
                'localField': "_id",
                'foreignField': "_id",
                'as': "project",
            }
        },
        # 3 Unwind the project list (there is always only one project)
        {
            '$unwind': {
                'path': '$project',
            }
        },
        # 4 Find all home projects
        {
            '$match': {
                'project.category': 'home'
            }
        },
        {
            '$count': 'tot'
        }
    ]
    c = current_app.db()['nodes']
    # If we provide a query, we extend the first $match step in the aggregation pipeline with
    # with the extra parameters (for example _created)
    if query:
        pipeline[0]['$match'].update(query)
    # Return either a list with one item or an empty list
    r = list(c.aggregate(pipeline=pipeline))
    count = 0 if not r else r[0]['tot']
    return count
Example #27
0
def get_user_list(user_list):
    if not user_list:
        return u'-nobody-'

    user_coll = current_app.db()['users']
    users = user_coll.find({'_id': {
        '$in': user_list
    }},
                           projection={
                               'full_name': 1,
                           })

    names = [user['full_name'] for user in users]
    return u', '.join(names)
Example #28
0
def gcs_move_to_bucket(file_id, dest_project_id, skip_gcs=False):
    """Moves a file from its own bucket to the new project_id bucket."""

    files_coll = current_app.db()['files']

    f = files_coll.find_one(file_id)
    if f is None:
        raise ValueError('File with _id: {} not found'.format(file_id))

    # Check that new backend differs from current one
    if f['backend'] != 'gcs':
        raise ValueError('Only Google Cloud Storage is supported for now.')

    # Move file and variations to the new bucket.
    if skip_gcs:
        log.warning(
            'NOT ACTUALLY MOVING file %s on GCS, just updating MongoDB',
            file_id)
    else:
        from pillar.api.file_storage_backends.gcs import GoogleCloudStorageBucket

        src_project = f['project']
        GoogleCloudStorageBucket.copy_to_bucket(f['file_path'], src_project,
                                                dest_project_id)
        for var in f.get('variations', []):
            GoogleCloudStorageBucket.copy_to_bucket(var['file_path'],
                                                    src_project,
                                                    dest_project_id)

    # Update the file document after moving was successful.
    log.info('Switching file %s to project %s', file_id, dest_project_id)
    update_result = files_coll.update_one(
        {'_id': file_id}, {'$set': {
            'project': dest_project_id
        }})
    if update_result.matched_count != 1:
        raise RuntimeError(
            'Unable to update file %s in MongoDB: matched_count=%i; modified_count=%i'
            % (file_id, update_result.matched_count,
               update_result.modified_count))

    log.info('Switching file %s: matched_count=%i; modified_count=%i', file_id,
             update_result.matched_count, update_result.modified_count)

    # Regenerate the links for this file
    f['project'] = dest_project_id
    generate_all_links(f, now=datetime.datetime.now(tz=bson.tz_util.utc))
Example #29
0
def move_to_bucket(file_id: ObjectId, dest_project_id: ObjectId, *, skip_storage=False):
    """Move a file + variations from its own bucket to the new project_id bucket.

    :param file_id: ID of the file to move.
    :param dest_project_id: Project to move to.
    :param skip_storage: If True, the storage bucket will not be touched.
        Only use this when you know what you're doing.
    """

    files_coll = current_app.db('files')
    f = files_coll.find_one(file_id)
    if f is None:
        raise ValueError(f'File with _id: {file_id} not found')

    # Move file and variations to the new bucket.
    if skip_storage:
        log.warning('NOT ACTUALLY MOVING file %s on storage, just updating MongoDB', file_id)
    else:
        from pillar.api.file_storage_backends import Bucket
        bucket_class = Bucket.for_backend(f['backend'])
        src_bucket = bucket_class(str(f['project']))
        dst_bucket = bucket_class(str(dest_project_id))

        src_blob = src_bucket.get_blob(f['file_path'])
        src_bucket.copy_blob(src_blob, dst_bucket)

        for var in f.get('variations', []):
            src_blob = src_bucket.get_blob(var['file_path'])
            src_bucket.copy_blob(src_blob, dst_bucket)

    # Update the file document after moving was successful.
    # No need to update _etag or _updated, since that'll be done when
    # the links are regenerated at the end of this function.
    log.info('Switching file %s to project %s', file_id, dest_project_id)
    update_result = files_coll.update_one({'_id': file_id},
                                          {'$set': {'project': dest_project_id}})
    if update_result.matched_count != 1:
        raise RuntimeError(
            'Unable to update file %s in MongoDB: matched_count=%i; modified_count=%i' % (
                file_id, update_result.matched_count, update_result.modified_count))

    log.info('Switching file %s: matched_count=%i; modified_count=%i',
             file_id, update_result.matched_count, update_result.modified_count)

    # Regenerate the links for this file
    f['project'] = dest_project_id
    generate_all_links(f, now=utils.utcnow())
Example #30
0
def create_groups():
    """Creates the admin/demo/subscriber groups."""

    import pprint

    group_ids = {}
    groups_coll = current_app.db('groups')

    for group_name in ['admin', 'demo', 'subscriber']:
        if groups_coll.find({'name': group_name}).count():
            log.info('Group %s already exists, skipping', group_name)
            continue
        result = groups_coll.insert_one({'name': group_name})
        group_ids[group_name] = result.inserted_id

    service.fetch_role_to_group_id_map()
    log.info('Created groups:\n%s', pprint.pformat(group_ids))
Example #31
0
def update_links(user_id: bson.ObjectId, links: list):
    """Update the links extension property."""

    from pymongo.results import UpdateResult

    assert isinstance(user_id, bson.ObjectId)

    users_coll = current_app.db('users')
    result: UpdateResult = users_coll.update_one(
        {'_id': user_id},
        {'$set': {
            'extension_props_public.dillo.links': links
        }},
    )

    if result.matched_count == 0:
        raise ValueError(f'User {user_id} not found.')
Example #32
0
def get_admin_group_id(project_id: ObjectId) -> ObjectId:
    assert isinstance(project_id, ObjectId)

    project = current_app.db('projects').find_one({'_id': project_id},
                                                  {'permissions': 1})
    if not project:
        raise ValueError(f'Project {project_id} does not exist.')

    # TODO: search through all groups to find the one with the project ID as its name,
    # or identify "the admin group" in a different way (for example the group with DELETE rights).
    try:
        admin_group_id = ObjectId(project['permissions']['groups'][0]['group'])
    except KeyError:
        raise ValueError(
            f'Project {project_id} does not seem to have an admin group')

    return admin_group_id
Example #33
0
def _manager_project(manager_id, project_url, action):
    from pillar.api.utils import str2id
    from flamenco import current_flamenco

    authentication.force_cli_user()
    manager_id = str2id(manager_id)

    # Find project
    projs_coll = current_app.db()['projects']
    proj = projs_coll.find_one({'url': project_url}, projection={'_id': 1})
    if not proj:
        log.error('Unable to find project url=%s', project_url)
        return 1

    project_id = proj['_id']
    ok = current_flamenco.manager_manager.api_assign_to_project(manager_id, project_id, action)
    if not ok:
        log.error('Unable to assign manager %s to project %s', manager_id, project_id)
        return 1