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)
def test_find_links_from_html(html, expected): assert find_links_from_html(html) == expected
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)