Esempio n. 1
0
    def upsert_release(self, project_name, version, username, user_ip,
                       classifiers=None, release_dependencies=None,
                       description=None, **additional_db_values):
        """
        Takes in the following:

        * project_name: the name of the package to insert
        * version: the version of the package to insert
        * username: username of the user upserting the package
        * user_ip: ip address of the user upserting the package
        * classifiers: a list of the classifiers to classify the release with
        * release_dependencies: a dictionary of
            'ReleaseDependencyKind.value: [specifier]' pairs.
        * description: a restructured text description of the release/project
        * additional_db_values: any other column in the release table,
            as specified by get_settable_release_columns

        and inserts the release (if one doesn't exist), or updates otherwise
        """
        is_update = self.get_release(project_name, version) is not None
        modified_elements = list(additional_db_values.keys())

        db.validate_argument_column_mapping(
            additional_db_values,
            releases,
            blacklist=['name', 'version', 'description', 'description_html',
                       '_pypi_ordering', '_pypi_hidden']
        )

        if not is_update:
            additional_db_values['name'] = project_name
            additional_db_values['version'] = version

        if description:
            modified_elements += ['description', 'description_html']
            additional_db_values['description'] = description
            additional_db_values['description_html'] = \
                readme.rst.render(description)[0]

        if len(additional_db_values) > 0:
            if is_update:
                self.engine.execute(
                    releases
                    .update()
                    .where(releases.columns.name == project_name)
                    .where(releases.columns.version == version)
                    .values(**additional_db_values)
                )
            else:
                self.engine.execute(
                    releases.insert().values(**additional_db_values)
                )

        # external tables

        # this is legacy behavior. According to PEP-438, we should
        # no longer support parsing urls from descriptions
        hosting_mode = self.get_hosting_mode(project_name)
        if hosting_mode in ('pypi-scrape-crawl', 'pypi-scrape') \
           and 'description_html' in additional_db_values:

            self.update_release_external_urls(
                project_name, version,
                utils.find_links_from_html(
                    additional_db_values['description_html']
                )
            )

        if classifiers:
            modified_elements.append('classifiers')
            self.update_release_classifiers(project_name, version,
                                            classifiers)

        if release_dependencies:
            self.update_release_dependencies(project_name, version,
                                             release_dependencies)

        if is_update:
            journal_message = 'update {0}'.format(','.join(modified_elements))
        else:
            journal_message = "new release"

        self._insert_journal_entry(project_name, version, journal_message,
                                   username, user_ip)

        # insert specific actions

        if not is_update:
            self._update_release_ordering(project_name)
Esempio n. 2
0
def test_find_links_from_html(html, expected):
    assert find_links_from_html(html) == expected
Esempio n. 3
0
    def upsert_release(self,
                       project_name,
                       version,
                       username,
                       user_ip,
                       classifiers=None,
                       release_dependencies=None,
                       description=None,
                       **additional_db_values):
        """
        Takes in the following:

        * project_name: the name of the package to insert
        * version: the version of the package to insert
        * username: username of the user upserting the package
        * user_ip: ip address of the user upserting the package
        * classifiers: a list of the classifiers to classify the release with
        * release_dependencies: a dictionary of
            'ReleaseDependencyKind.value: [specifier]' pairs.
        * description: a restructured text description of the release/project
        * additional_db_values: any other column in the release table,
            as specified by get_settable_release_columns

        and inserts the release (if one doesn't exist), or updates otherwise
        """
        is_update = self.get_release(project_name, version) is not None
        modified_elements = list(additional_db_values.keys())

        db.validate_argument_column_mapping(additional_db_values,
                                            releases,
                                            blacklist=[
                                                'name', 'version',
                                                'description',
                                                'description_html',
                                                '_pypi_ordering',
                                                '_pypi_hidden'
                                            ])

        if not is_update:
            additional_db_values['name'] = project_name
            additional_db_values['version'] = version

        if description:
            modified_elements += ['description', 'description_html']
            additional_db_values['description'] = description
            additional_db_values['description_html'] = \
                readme.rst.render(description)[0]

        if len(additional_db_values) > 0:
            if is_update:
                self.engine.execute(releases.update().where(
                    releases.columns.name == project_name).where(
                        releases.columns.version == version).values(
                            **additional_db_values))
            else:
                self.engine.execute(
                    releases.insert().values(**additional_db_values))

        # external tables

        # this is legacy behavior. According to PEP-438, we should
        # no longer support parsing urls from descriptions
        hosting_mode = self.get_hosting_mode(project_name)
        if hosting_mode in ('pypi-scrape-crawl', 'pypi-scrape') \
           and 'description_html' in additional_db_values:

            self.update_release_external_urls(
                project_name, version,
                utils.find_links_from_html(
                    additional_db_values['description_html']))

        if classifiers:
            modified_elements.append('classifiers')
            self.update_release_classifiers(project_name, version, classifiers)

        if release_dependencies:
            self.update_release_dependencies(project_name, version,
                                             release_dependencies)

        if is_update:
            journal_message = 'update {0}'.format(','.join(modified_elements))
        else:
            journal_message = "new release"

        self._insert_journal_entry(project_name, version, journal_message,
                                   username, user_ip)

        # insert specific actions

        if not is_update:
            self._update_release_ordering(project_name)
Esempio n. 4
0
def test_find_links_from_html(html, expected):
    assert find_links_from_html(html) == expected