示例#1
0
    def test_list_packages_items_per_page_with_page(self):
        """Assert retrieving other pages works."""
        project = models.Project(name="requests",
                                 homepage="https://pypi.io/project/requests",
                                 backend="PyPI")
        fedora_package = models.Packages(distro_name="Fedora",
                                         project=project,
                                         package_name="python-requests")
        debian_package = models.Packages(distro_name="Debian",
                                         project=project,
                                         package_name="python-requests")
        Session.add_all([project, fedora_package, debian_package])
        Session.commit()
        output = self.app.get("/api/v2/packages/?items_per_page=1&page=2")
        self.assertEqual(output.status_code, 200)
        data = _read_json(output)

        exp = {
            "page":
            2,
            "items_per_page":
            1,
            "total_items":
            2,
            "items": [{
                "distribution": "Debian",
                "name": "python-requests",
                "project": "requests",
                "ecosystem": "pypi",
            }],
        }

        self.assertEqual(data, exp)
示例#2
0
    def test_filter_distribution(self):
        """Assert retrieving other pages works."""
        project = models.Project(
            name='requests',
            homepage='https://pypi.io/project/requests',
            backend='PyPI',
        )
        fedora_package = models.Packages(distro_name='Fedora',
                                         project=project,
                                         package_name='python-requests')
        debian_package = models.Packages(distro_name='Debian',
                                         project=project,
                                         package_name='python-requests')
        Session.add_all([project, fedora_package, debian_package])
        Session.commit()
        fedora = self.app.get('/api/v2/packages/?distribution=Fedora')
        debian = self.app.get('/api/v2/packages/?distribution=Debian')
        self.assertEqual(fedora.status_code, 200)
        self.assertEqual(debian.status_code, 200)
        fedora_data = _read_json(fedora)
        debian_data = _read_json(debian)

        fedora_exp = {
            'page':
            1,
            'items_per_page':
            25,
            'total_items':
            1,
            'items': [
                {
                    "distribution": "Fedora",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi"
                },
            ]
        }
        debian_exp = {
            'page':
            1,
            'items_per_page':
            25,
            'total_items':
            1,
            'items': [
                {
                    "distribution": "Debian",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi"
                },
            ]
        }

        self.assertEqual(fedora_data, fedora_exp)
        self.assertEqual(debian_data, debian_exp)
示例#3
0
def create_package(session):
    """ Create some basic packages to work with. """
    package = models.Packages(project_id=1, distro_name="Fedora", package_name="geany")
    session.add(package)

    package = models.Packages(
        project_id=2, distro_name="Fedora", package_name="subsurface"
    )
    session.add(package)

    session.commit()
示例#4
0
    def test_packages(self):
        """Assert packages are returned when they exist."""
        project = models.Project(
            name='requests',
            homepage='https://pypi.io/project/requests',
            backend='PyPI',
        )
        fedora_package = models.Packages(distro_name='Fedora',
                                         project=project,
                                         package_name='python-requests')
        debian_package = models.Packages(distro_name='Debian',
                                         project=project,
                                         package_name='python-requests')
        jcline_package = models.Packages(distro_name='jcline linux',
                                         project=project,
                                         package_name='requests')
        Session.add_all(
            [project, fedora_package, debian_package, jcline_package])
        Session.commit()

        output = self.app.get('/api/v2/packages/')
        self.assertEqual(output.status_code, 200)
        data = _read_json(output)

        exp = {
            'page':
            1,
            'items_per_page':
            25,
            'total_items':
            3,
            'items': [
                {
                    "distribution": "Fedora",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi"
                },
                {
                    "distribution": "Debian",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi"
                },
                {
                    "distribution": "jcline linux",
                    "name": "requests",
                    "project": "requests",
                    "ecosystem": "pypi"
                },
            ]
        }

        self.assertEqual(data, exp)
示例#5
0
    def test_packages(self):
        """Assert packages are returned when they exist."""
        project = models.Project(name="requests",
                                 homepage="https://pypi.io/project/requests",
                                 backend="PyPI")
        fedora_package = models.Packages(distro_name="Fedora",
                                         project=project,
                                         package_name="python-requests")
        debian_package = models.Packages(distro_name="Debian",
                                         project=project,
                                         package_name="python-requests")
        jcline_package = models.Packages(distro_name="jcline linux",
                                         project=project,
                                         package_name="requests")
        Session.add_all(
            [project, fedora_package, debian_package, jcline_package])
        Session.commit()

        output = self.app.get("/api/v2/packages/")
        self.assertEqual(output.status_code, 200)
        data = _read_json(output)

        exp = {
            "page":
            1,
            "items_per_page":
            25,
            "total_items":
            3,
            "items": [
                {
                    "distribution": "Fedora",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi",
                },
                {
                    "distribution": "Debian",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi",
                },
                {
                    "distribution": "jcline linux",
                    "name": "requests",
                    "project": "requests",
                    "ecosystem": "pypi",
                },
            ],
        }

        self.assertEqual(data, exp)
示例#6
0
    def test_filter_distribution(self):
        """Assert retrieving other pages works."""
        project = models.Project(name="requests",
                                 homepage="https://pypi.io/project/requests",
                                 backend="PyPI")
        fedora_package = models.Packages(distro_name="Fedora",
                                         project=project,
                                         package_name="python-requests")
        debian_package = models.Packages(distro_name="Debian",
                                         project=project,
                                         package_name="python-requests")
        Session.add_all([project, fedora_package, debian_package])
        Session.commit()
        fedora = self.app.get("/api/v2/packages/?distribution=Fedora")
        debian = self.app.get("/api/v2/packages/?distribution=Debian")
        self.assertEqual(fedora.status_code, 200)
        self.assertEqual(debian.status_code, 200)
        fedora_data = _read_json(fedora)
        debian_data = _read_json(debian)

        fedora_exp = {
            "page":
            1,
            "items_per_page":
            25,
            "total_items":
            1,
            "items": [{
                "distribution": "Fedora",
                "name": "python-requests",
                "project": "requests",
                "ecosystem": "pypi",
            }],
        }
        debian_exp = {
            "page":
            1,
            "items_per_page":
            25,
            "total_items":
            1,
            "items": [{
                "distribution": "Debian",
                "name": "python-requests",
                "project": "requests",
                "ecosystem": "pypi",
            }],
        }

        self.assertEqual(fedora_data, fedora_exp)
        self.assertEqual(debian_data, debian_exp)
示例#7
0
    def setUp(self):
        super(EditProjectMappingTests, self).setUp()

        # Set up a mapping to edit
        session = Session()
        self.user = models.User(
            email='*****@*****.**',
            username='******',
        )
        user_social_auth = social_models.UserSocialAuth(user_id=self.user.id,
                                                        user=self.user)

        self.session.add(self.user)
        self.session.add(user_social_auth)
        self.distro1 = models.Distro(name='CentOS')
        self.distro2 = models.Distro(name='Fedora')
        self.project = models.Project(
            name='python_project',
            homepage='https://example.com/python_project',
            backend='PyPI',
            ecosystem_name='pypi',
        )
        self.package = models.Packages(package_name='python_project',
                                       distro=self.distro1.name,
                                       project=self.project)
        session.add_all(
            [self.distro1, self.distro2, self.project, self.package])
        session.commit()
        self.client = self.flask_app.test_client()
示例#8
0
    def test_distro_delete_cascade(self):
        """ Assert deletion of mapped packages when project is deleted """
        project = models.Project(
            name="test",
            homepage="https://example.com",
            backend="custom",
            ecosystem_name="pypi",
            version_scheme="Invalid",
        )
        self.session.add(project)

        distro = models.Distro(name="Fedora")
        self.session.add(distro)

        package = models.Packages(project_id=1,
                                  distro_name="Fedora",
                                  package_name="test")
        self.session.add(package)
        self.session.commit()

        distros = self.session.query(models.Distro).all()

        self.assertEqual(len(distros), 1)
        self.assertEqual(len(distros[0].package), 1)

        self.session.delete(distros[0])
        self.session.commit()

        distros = self.session.query(models.Distro).all()
        packages = self.session.query(models.Packages).all()

        self.assertEqual(len(distros), 0)
        self.assertEqual(len(packages), 0)
示例#9
0
    def test_map_project_no_project_for_package(self):
        """ Test package duplicity when package is not associated to project """
        create_distro(self.session)
        create_project(self.session)

        pkg = models.Packages(distro_name="Fedora",
                              project_id=None,
                              package_name="geany")
        self.session.add(pkg)
        self.session.commit()

        distro_objs = self.session.query(models.Distro).all()
        project_obj = models.Project.get(self.session, 1)
        self.assertEqual(project_obj.name, "geany")
        self.assertEqual(len(project_obj.packages), 0)
        self.assertEqual(distro_objs[0].name, "Fedora")

        utilities.map_project(
            self.session,
            project=project_obj,
            package_name="geany",
            distribution="Fedora",
            user_id="*****@*****.**",
            old_package_name=None,
        )
        self.session.commit()

        project_obj = models.Project.get(self.session, 1)
        packages = self.session.query(models.Packages).all()
        self.assertEqual(project_obj.name, "geany")
        self.assertEqual(len(project_obj.packages), 1)
        self.assertEqual(len(packages), 1)
        self.assertEqual(project_obj.packages[0].package_name, "geany")
        self.assertEqual(project_obj.packages[0].distro_name, "Fedora")
示例#10
0
    def test_is_delete_candidate_mapping_no_version(self):
        """
        Assert that project is marked as delete candidate,
        if it has mapping added and no version.
        """
        project = models.Project(
            name="Foobar",
            backend="GitHub",
            homepage="www.fakeproject.com",
            next_check=arrow.utcnow().datetime,
            error_counter=100,
        )
        self.session.add(project)
        self.session.commit()

        distro = models.Distro(name="Fedora")
        self.session.add(distro)
        self.session.commit()

        mapping = models.Packages(distro_name="Fedora", project_id=project.id)
        self.session.add(mapping)
        self.session.commit()

        result = self.checker.is_delete_candidate(project)

        self.assertTrue(result)
    def setUp(self):
        super(DeleteProjectMappingTests, self).setUp()
        self.project = models.Project(
            name='test_project',
            homepage='https://example.com/test_project',
            backend='PyPI',
        )
        self.distro = models.Distro(name='Fedora')
        self.package = models.Packages(
            distro=self.distro.name, project=self.project, package_name='test-project')

        # Add a regular user and an admin user
        session = Session()
        self.user = models.User(email='*****@*****.**', username='******')
        self.admin = models.User(email='*****@*****.**', username='******')

        session.add_all([self.user, self.admin, self.distro, self.project, self.package])
        session.commit()

        mock_config = mock.patch.dict(
            models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]})
        mock_config.start()
        self.addCleanup(mock_config.stop)

        self.client = self.flask_app.test_client()
示例#12
0
文件: base.py 项目: livingeek/anitya
def create_package(session):
    """ Create some basic packages to work with. """
    package = models.Packages(
        project_id=1,
        distro='Fedora',
        package_name='geany',
    )
    session.add(package)

    package = models.Packages(
        project_id=2,
        distro='Fedora',
        package_name='subsurface',
    )
    session.add(package)

    session.commit()
示例#13
0
    def test_list_packages_items_per_page_with_page(self):
        """Assert retrieving other pages works."""
        project = models.Project(
            name='requests',
            homepage='https://pypi.io/project/requests',
            backend='PyPI',
        )
        fedora_package = models.Packages(distro_name='Fedora',
                                         project=project,
                                         package_name='python-requests')
        debian_package = models.Packages(distro_name='Debian',
                                         project=project,
                                         package_name='python-requests')
        Session.add_all([project, fedora_package, debian_package])
        Session.commit()
        output = self.app.get('/api/v2/packages/?items_per_page=1&page=2')
        self.assertEqual(output.status_code, 200)
        data = _read_json(output)

        exp = {
            'page':
            2,
            'items_per_page':
            1,
            'total_items':
            2,
            'items': [
                {
                    "distribution": "Debian",
                    "name": "python-requests",
                    "project": "requests",
                    "ecosystem": "pypi"
                },
            ]
        }

        self.assertEqual(data, exp)
示例#14
0
    def test_project_search_by_distro(self):
        """
        Assert that only projects with mappings to specific distro
        are returned when distro is provided.
        """
        create_project(self.session)
        create_package(self.session)
        # Create mapping for another distro to be sure that only Fedora mappings
        # are taken into account
        package = models.Packages(distro_name="Debian", project_id=3)
        self.session.add(package)
        self.session.commit()

        projects = models.Project.search(self.session, "*", distro="Fedora")
        self.assertEqual(len(projects), 2)
示例#15
0
    def test_project_delete_cascade(self):
        """ Assert deletion of mapped packages when project is deleted """
        project = models.Project(
            name='test',
            homepage='https://example.com',
            backend='custom',
            ecosystem_name='pypi',
            version_scheme='Invalid',
        )
        self.session.add(project)

        package = models.Packages(
            project_id=1,
            distro_name='Fedora',
            package_name='test',
        )
        self.session.add(package)
        self.session.commit()

        projects = self.session.query(models.Project).all()
        self.assertEqual(len(projects), 1)
        self.assertEqual(len(projects[0].package), 1)

        self.session.delete(projects[0])
        self.session.commit()

        projects = self.session.query(models.Project).all()
        packages = self.session.query(models.Packages).all()
        self.assertEqual(len(projects), 0)
        self.assertEqual(len(packages), 0)

        create_flagged_project(self.session)
        projects = self.session.query(models.Project).all()
        self.assertEqual(len(projects), 1)
        self.assertEqual(len(projects[0].flags), 1)

        self.session.delete(projects[0])
        self.session.commit()

        projects = self.session.query(models.Project).all()
        packages = self.session.query(models.ProjectFlag).all()
        self.assertEqual(len(projects), 0)
        self.assertEqual(len(packages), 0)
示例#16
0
    def test_clashing_package_name(self):
        """Assert two projects can't map to the same package name in a distro."""
        # Set up a package to clash with.
        session = Session()
        best_project = models.Project(
            name='best_project',
            homepage='https://example.com/best_project',
            backend='PyPI',
            ecosystem_name='pypi',
        )
        best_package = models.Packages(package_name='best_project',
                                       distro=self.distro1.name,
                                       project=best_project)
        session.add_all([best_project, best_package])
        session.commit()

        with login_user(self.flask_app, self.user):
            pre_edit_output = self.client.get('/project/1/map/1')
            csrf_token = pre_edit_output.data.split(
                b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0]
            data = {
                'package_name': self.project.name,
                'distro': self.distro1.name,
                'csrf_token': csrf_token,
            }
            output = self.client.post('/project/1/map/1',
                                      data=data,
                                      follow_redirects=True)

            self.assertEqual(output.status_code, 200)
            self.assertEqual(2, models.Packages.query.count())
            self.assertEqual(
                1,
                models.Packages.query.filter_by(
                    package_name='best_project').count())
            self.assertEqual(
                1,
                models.Packages.query.filter_by(
                    package_name='python_project').count())
            self.assertTrue(b'Could not edit the mapping' in output.data)
示例#17
0
def map_project(session,
                project,
                package_name,
                distribution,
                user_id,
                old_package_name=None,
                old_distro_name=None):
    """
    Map a project to a distribution.

    Args:
        session (sqlalchemy.orm.session.Session): The database session.
        project (anitya.db.modelss.Project): The project to map to a distribution.
        package_name (str): The name of the mapped package.
        distribution (str): The name of the distribution.
        user_id (str): The user ID.
        old_package_name (str): The name of the old package mapping, if this is being
            used to edit a mapping.
        old_distro_name (str): The name of the old distro of the package mapping, if this
            is being used to edit a mapping.
    """
    distribution = distribution.strip()

    distro_obj = models.Distro.get(session, distribution)

    if not distro_obj:
        distro_obj = models.Distro(name=distribution)
        log(session,
            distro=distro_obj,
            topic='distro.add',
            message=dict(
                agent=user_id,
                distro=distro_obj.name,
            ))
        session.add(distro_obj)
        try:
            session.flush()
        except SQLAlchemyError as err:  # pragma: no cover
            # We cannot test this situation
            session.rollback()
            raise exceptions.AnityaException(
                'Could not add the distribution %s to the database, '
                'please inform an admin.' % distribution, 'errors')

    pkgname = old_package_name or package_name
    distro = old_distro_name or distribution
    pkg = models.Packages.get(session, project.id, distro, pkgname)

    # See if the new mapping would clash with an existing mapping
    try:
        other_pkg = models.Packages.query.filter_by(
            distro=distribution, package_name=package_name).one()
    except NoResultFound:
        other_pkg = None
    if other_pkg:
        raise exceptions.AnityaInvalidMappingException(pkgname, distro,
                                                       package_name,
                                                       distribution,
                                                       other_pkg.project.id,
                                                       other_pkg.project.name)

    edited = None
    if not pkg:
        topic = 'project.map.new'
        if not other_pkg:
            pkg = models.Packages(distro=distro_obj.name,
                                  project_id=project.id,
                                  package_name=package_name)
        else:
            other_pkg.project = project
            pkg = other_pkg
    else:
        topic = 'project.map.update'
        edited = []
        if pkg.distro != distro_obj.name:
            pkg.distro = distro_obj.name
            edited.append('distribution')
        if pkg.package_name != package_name:
            pkg.package_name = package_name
            edited.append('package_name')

    session.add(pkg)
    try:
        session.flush()
    except SQLAlchemyError as err:  # pragma: no cover
        _log.exception(err)
        # We cannot test this situation
        session.rollback()
        raise exceptions.AnityaException(
            'Could not add the mapping of %s to %s, please inform an '
            'admin.' % (package_name, distribution))

    message = dict(
        agent=user_id,
        project=project.name,
        distro=distro_obj.name,
        new=package_name,
    )
    if edited:
        message['prev'] = old_package_name or package_name
        message['edited'] = edited

    log(
        session,
        project=project,
        distro=distro_obj,
        topic=topic,
        message=message,
    )

    return pkg
示例#18
0
    def post(self):
        """
        Create a new package associated with an existing project and distribution.

        **Example request**:

        .. sourcecode:: http

            POST /api/v2/packages/ HTTP/1.1
            Accept: application/json
            Accept-Encoding: gzip, deflate
            Authorization: Token gAOFi2wQPzUJFIfDkscAKjbJfXELCz0r44m57Ur2
            Connection: keep-alive
            Content-Length: 120
            Content-Type: application/json
            Host: localhost:5000
            User-Agent: HTTPie/0.9.4

            {
                "distribution": "Fedora",
                "package_name": "python-requests",
                "project_ecosystem": "pypi",
                "project_name": "requests"
            }

        .. sourcecode:: http

            HTTP/1.0 201 CREATED
            Content-Length: 69
            Content-Type: application/json
            Date: Mon, 15 Jan 2018 21:49:01 GMT
            Server: Werkzeug/0.14.1 Python/2.7.14

            {
                "distribution": "Fedora",
                "name": "python-requests"
            }


        :reqheader Authorization: API token to use for authentication
        :reqjson string distribution: The name of the distribution that contains this
            package.
        :reqjson string package_name: The name of the package in the distribution repository.
        :reqjson string project_name: The project name in Anitya.
        :reqjson string project_ecosystem: The ecosystem the project is a part of.
            If it's not part of an ecosystem, use the homepage used in the Anitya project.

        :statuscode 201: When the package was successfully created.
        :statuscode 400: When required arguments are missing or malformed.
        :statuscode 401: When your access token is missing or invalid
        :statuscode 409: When the package already exists.
        """
        distribution_help = _(
            "The name of the distribution that contains this package.")
        package_name_help = _(
            "The name of the package in the distribution repository.")
        project_name_help = _("The project name in Anitya.")
        project_ecosystem_help = _(
            "The ecosystem the project is a part of. If it's not part of an ecosystem,"
            " use the homepage used in the Anitya project.")

        parser = _BASE_ARG_PARSER.copy()
        parser.add_argument("distribution",
                            type=str,
                            help=distribution_help,
                            required=True)
        parser.add_argument("package_name",
                            type=str,
                            help=package_name_help,
                            required=True)
        parser.add_argument("project_name",
                            type=str,
                            help=project_name_help,
                            required=True)
        parser.add_argument("project_ecosystem",
                            type=str,
                            help=project_ecosystem_help,
                            required=True)
        args = parser.parse_args(strict=True)
        try:
            project = models.Project.query.filter(
                func.lower(models.Project.name) == func.lower(
                    args.project_name),
                func.lower(models.Project.ecosystem_name) == func.lower(
                    args.project_ecosystem),
            ).one()
        except NoResultFound:
            return (
                {
                    "error":
                    'Project "{}" in ecosystem "{}" not found'.format(
                        args.project_name, args.project_ecosystem)
                },
                400,
            )

        try:
            distro = models.Distro.query.filter(
                func.lower(models.Distro.name) == func.lower(
                    args.distribution)).one()
        except NoResultFound:
            return (
                {
                    "error":
                    'Distribution "{}" not found'.format(args.distribution)
                },
                400,
            )

        try:
            package = models.Packages(distro_name=distro.name,
                                      project=project,
                                      package_name=args.package_name)

            Session.add(package)
            Session.commit()

            message = dict(
                agent=flask_login.current_user.email,
                project=project.name,
                distro=distro.name,
                new=package.package_name,
            )
            utilities.publish_message(
                project=project.__json__(),
                distro=distro.__json__(),
                topic="project.map.new",
                message=message,
            )
            return {
                "distribution": distro.name,
                "name": package.package_name
            }, 201
        except IntegrityError:
            Session.rollback()
            return {"error": "package already exists in distribution"}, 409
示例#19
0
def map_project(
    session,
    project,
    package_name,
    distribution,
    user_id,
    old_package_name=None,
    old_distro_name=None,
):
    """
    Map a project to a distribution.

    Args:
        session (sqlalchemy.orm.session.Session): The database session.
        project (anitya.db.modelss.Project): The project to map to a distribution.
        package_name (str): The name of the mapped package.
        distribution (str): The name of the distribution.
        user_id (str): The user ID.
        old_package_name (str): The name of the old package mapping, if this is being
            used to edit a mapping.
        old_distro_name (str): The name of the old distro of the package mapping, if this
            is being used to edit a mapping.
    """
    distribution = distribution.strip()

    distro_obj = models.Distro.get(session, distribution)

    if not distro_obj:
        distro_obj = models.Distro(name=distribution)
        session.add(distro_obj)
        try:
            session.flush()
        except SQLAlchemyError:
            session.rollback()
            raise exceptions.AnityaException(
                "Could not add the distribution %s to the database, "
                "please inform an admin." % distribution,
                "errors",
            )

        log(
            session,
            distro=distro_obj.__json__(),
            topic="distro.add",
            message=dict(agent=user_id, distro=distro_obj.name),
        )
        session.add(distro_obj)
        try:
            session.flush()
        except SQLAlchemyError:  # pragma: no cover
            # We cannot test this situation
            session.rollback()
            raise exceptions.AnityaException(
                "Could not add the distribution %s to the database, "
                "please inform an admin." % distribution,
                "errors",
            )

    pkgname = old_package_name or package_name
    distro = old_distro_name or distribution
    pkg = models.Packages.get(session, project.id, distro, pkgname)

    # See if the new mapping would clash with an existing mapping
    try:
        other_pkg = models.Packages.query.filter_by(
            distro_name=distribution, package_name=package_name
        ).one()
    except NoResultFound:
        other_pkg = None
    # Only raise exception if the package is already associated
    # to project
    if other_pkg and other_pkg.project:
        raise exceptions.AnityaInvalidMappingException(
            pkgname,
            distro,
            package_name,
            distribution,
            other_pkg.project.id,
            other_pkg.project.name,
        )

    edited = None
    if not pkg:
        topic = "project.map.new"
        if not other_pkg:
            pkg = models.Packages(
                distro_name=distro_obj.name,
                project_id=project.id,
                package_name=package_name,
            )
        else:
            other_pkg.project = project
            pkg = other_pkg
    else:
        topic = "project.map.update"
        edited = []
        if pkg.distro_name != distro_obj.name:
            pkg.distro_name = distro_obj.name
            edited.append("distribution")
        if pkg.package_name != package_name:
            pkg.package_name = package_name
            edited.append("package_name")

    session.add(pkg)
    try:
        session.flush()
    except SQLAlchemyError as err:
        _log.exception(err)
        session.rollback()
        raise exceptions.AnityaException(
            "Could not add the mapping of %s to %s, please inform an "
            "admin." % (package_name, distribution)
        )

    message = dict(
        agent=user_id, project=project.name, distro=distro_obj.name, new=package_name
    )
    if edited:
        message["prev"] = old_package_name or package_name
        message["edited"] = edited

    log(
        session,
        project=project.__json__(),
        distro=distro_obj.__json__(),
        topic=topic,
        message=message,
    )

    return pkg