diff --git a/tests/common/db/packaging.py b/tests/common/db/packaging.py index b516efb3e06e..15396d7b941f 100644 --- a/tests/common/db/packaging.py +++ b/tests/common/db/packaging.py @@ -10,7 +10,6 @@ from warehouse.observations.models import ObservationKind from warehouse.packaging.models import ( - AlternateRepository, Dependency, DependencyKind, Description, @@ -202,13 +201,3 @@ class Meta: ) name = factory.Faker("pystr", max_chars=12) prohibited_by = factory.SubFactory(UserFactory) - - -class AlternateRepositoryFactory(WarehouseFactory): - class Meta: - model = AlternateRepository - - name = factory.Faker("word") - url = factory.Faker("uri") - description = factory.Faker("text") - project = factory.SubFactory(ProjectFactory) diff --git a/tests/unit/api/test_simple.py b/tests/unit/api/test_simple.py index 431408a61dd8..5b96f6b6b9f7 100644 --- a/tests/unit/api/test_simple.py +++ b/tests/unit/api/test_simple.py @@ -13,7 +13,6 @@ from ...common.db.accounts import UserFactory from ...common.db.packaging import ( - AlternateRepositoryFactory, FileFactory, JournalEntryFactory, ProjectFactory, @@ -210,7 +209,6 @@ def test_no_files_no_serial(self, db_request, content_type, renderer_override): "project-status": {"status": "active"}, "files": [], "versions": [], - "alternate-locations": [], } context = _update_context(context, content_type, renderer_override) assert simple.simple_detail(project, db_request) == context @@ -232,10 +230,6 @@ def test_no_files_with_serial(self, db_request, content_type, renderer_override) db_request.matchdict["name"] = project.normalized_name user = UserFactory.create() je = JournalEntryFactory.create(name=project.name, submitted_by=user) - als = [ - AlternateRepositoryFactory.create(project=project), - AlternateRepositoryFactory.create(project=project), - ] context = { "meta": {"_last-serial": je.id, "api-version": API_VERSION}, @@ -243,7 +237,6 @@ def test_no_files_with_serial(self, db_request, content_type, renderer_override) "project-status": {"status": "active"}, "files": [], "versions": [], - "alternate-locations": sorted(al.url for al in als), } context = _update_context(context, content_type, renderer_override) assert simple.simple_detail(project, db_request) == context @@ -296,7 +289,6 @@ def test_with_files_no_serial(self, db_request, content_type, renderer_override) } for f in files ], - "alternate-locations": [], } context = _update_context(context, content_type, renderer_override) assert simple.simple_detail(project, db_request) == context @@ -349,7 +341,6 @@ def test_with_files_with_serial(self, db_request, content_type, renderer_overrid } for f in files ], - "alternate-locations": [], } context = _update_context(context, content_type, renderer_override) assert simple.simple_detail(project, db_request) == context @@ -447,7 +438,6 @@ def test_with_files_with_version_multi_digit( } for f in files ], - "alternate-locations": [], } context = _update_context(context, content_type, renderer_override) assert simple.simple_detail(project, db_request) == context @@ -480,7 +470,6 @@ def test_with_files_quarantined_omitted_from_index( "project-status": {"status": "quarantined"}, "files": [], "versions": [], - "alternate-locations": [], } context = _update_context(context, content_type, renderer_override) @@ -513,7 +502,6 @@ def test_with_archived_project( "project-status": {"status": "archived"}, "files": [], "versions": [], - "alternate-locations": [], } context = _update_context(context, content_type, renderer_override) @@ -539,7 +527,6 @@ def test_with_quarantine_exit_project( "project-status": {"status": "active"}, "files": [], "versions": [], - "alternate-locations": [], } context = _update_context(context, content_type, renderer_override) @@ -660,7 +647,6 @@ def route_url(route, **kw): } for f in files ], - "alternate-locations": [], } context = _update_context(context, content_type, renderer_override) diff --git a/tests/unit/manage/test_views.py b/tests/unit/manage/test_views.py index d3b1647fce46..4455341bf478 100644 --- a/tests/unit/manage/test_views.py +++ b/tests/unit/manage/test_views.py @@ -66,7 +66,6 @@ TeamRoleFactory, ) from ...common.db.packaging import ( - AlternateRepositoryFactory, FileEventFactory, FileFactory, JournalEntryFactory, @@ -2986,260 +2985,6 @@ def test_manage_project_settings_in_organization_owned(self, monkeypatch): pretend.call(organization_choices={organization_managed}) ] - def test_add_alternate_repository(self, monkeypatch, db_request): - project = ProjectFactory.create(name="foo") - - db_request.POST = MultiDict( - { - "display_name": "foo alt repo", - "link_url": "https://example.org", - "description": "foo alt repo descr", - "alternate_repository_location": "add", - } - ) - db_request.flags = pretend.stub(enabled=pretend.call_recorder(lambda *a: False)) - db_request.route_path = pretend.call_recorder(lambda *a, **kw: "/the-redirect") - db_request.session = pretend.stub( - flash=pretend.call_recorder(lambda *a, **kw: None) - ) - db_request.user = UserFactory.create() - - RoleFactory.create(project=project, user=db_request.user, role_name="Owner") - - add_alternate_repository_form_class = pretend.call_recorder( - views.AddAlternateRepositoryForm - ) - monkeypatch.setattr( - views, - "AddAlternateRepositoryForm", - add_alternate_repository_form_class, - ) - - settings_views = views.ManageProjectSettingsViews(project, db_request) - result = settings_views.add_project_alternate_repository() - - assert isinstance(result, HTTPSeeOther) - assert result.headers["Location"] == "/the-redirect" - assert db_request.session.flash.calls == [ - pretend.call("Added alternate repository 'foo alt repo'", queue="success") - ] - assert db_request.route_path.calls == [ - pretend.call("manage.project.settings", project_name="foo") - ] - assert add_alternate_repository_form_class.calls == [ - pretend.call(db_request.POST) - ] - - def test_add_alternate_repository_invalid(self, monkeypatch, db_request): - project = ProjectFactory.create(name="foo") - - db_request.POST = MultiDict( - { - "display_name": "foo alt repo", - "link_url": "invalid link", - "description": "foo alt repo descr", - "alternate_repository_location": "add", - } - ) - db_request.flags = pretend.stub(enabled=pretend.call_recorder(lambda *a: False)) - db_request.route_path = pretend.call_recorder(lambda *a, **kw: "/the-redirect") - db_request.session = pretend.stub( - flash=pretend.call_recorder(lambda *a, **kw: None) - ) - db_request.user = UserFactory.create() - - RoleFactory.create(project=project, user=db_request.user, role_name="Owner") - - add_alternate_repository_form_class = pretend.call_recorder( - views.AddAlternateRepositoryForm - ) - monkeypatch.setattr( - views, - "AddAlternateRepositoryForm", - add_alternate_repository_form_class, - ) - - settings_views = views.ManageProjectSettingsViews(project, db_request) - result = settings_views.add_project_alternate_repository() - - assert isinstance(result, HTTPSeeOther) - assert result.headers["Location"] == "/the-redirect" - assert db_request.session.flash.calls == [ - pretend.call("Invalid alternate repository location details", queue="error") - ] - assert db_request.route_path.calls == [ - pretend.call("manage.project.settings", project_name="foo") - ] - assert add_alternate_repository_form_class.calls == [ - pretend.call(db_request.POST) - ] - - def test_delete_alternate_repository(self, db_request): - project = ProjectFactory.create(name="foo") - alt_repo = AlternateRepositoryFactory.create(project=project) - - db_request.POST = MultiDict( - { - "alternate_repository_id": str(alt_repo.id), - "confirm_alternate_repository_name": alt_repo.name, - "alternate_repository_location": "delete", - } - ) - db_request.flags = pretend.stub(enabled=pretend.call_recorder(lambda *a: False)) - db_request.route_path = pretend.call_recorder(lambda *a, **kw: "/the-redirect") - db_request.session = pretend.stub( - flash=pretend.call_recorder(lambda *a, **kw: None) - ) - db_request.user = UserFactory.create() - - RoleFactory.create(project=project, user=db_request.user, role_name="Owner") - - settings_views = views.ManageProjectSettingsViews(project, db_request) - result = settings_views.delete_project_alternate_repository() - - assert isinstance(result, HTTPSeeOther) - assert result.headers["Location"] == "/the-redirect" - assert db_request.session.flash.calls == [ - pretend.call( - f"Deleted alternate repository '{alt_repo.name}'", queue="success" - ) - ] - assert db_request.route_path.calls == [ - pretend.call("manage.project.settings", project_name="foo") - ] - - @pytest.mark.parametrize("alt_repo_id", [None, "", "blah"]) - def test_delete_alternate_repository_invalid_id(self, db_request, alt_repo_id): - project = ProjectFactory.create(name="foo") - alt_repo = AlternateRepositoryFactory.create(project=project) - - db_request.POST = MultiDict( - { - "alternate_repository_id": alt_repo_id, - "confirm_alternate_repository_name": alt_repo.name, - "alternate_repository_location": "delete", - } - ) - db_request.flags = pretend.stub(enabled=pretend.call_recorder(lambda *a: False)) - db_request.route_path = pretend.call_recorder(lambda *a, **kw: "/the-redirect") - db_request.session = pretend.stub( - flash=pretend.call_recorder(lambda *a, **kw: None) - ) - db_request.user = UserFactory.create() - - RoleFactory.create(project=project, user=db_request.user, role_name="Owner") - - settings_views = views.ManageProjectSettingsViews(project, db_request) - result = settings_views.delete_project_alternate_repository() - - assert isinstance(result, HTTPSeeOther) - assert result.headers["Location"] == "/the-redirect" - assert db_request.session.flash.calls == [ - pretend.call("Invalid alternate repository id", queue="error") - ] - assert db_request.route_path.calls == [ - pretend.call("manage.project.settings", project_name="foo") - ] - - def test_delete_alternate_repository_wrong_id(self, db_request): - project = ProjectFactory.create(name="foo") - alt_repo = AlternateRepositoryFactory.create(project=project) - - db_request.POST = MultiDict( - { - "alternate_repository_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", - "confirm_alternate_repository_name": alt_repo.name, - "alternate_repository_location": "delete", - } - ) - db_request.flags = pretend.stub(enabled=pretend.call_recorder(lambda *a: False)) - db_request.route_path = pretend.call_recorder(lambda *a, **kw: "/the-redirect") - db_request.session = pretend.stub( - flash=pretend.call_recorder(lambda *a, **kw: None) - ) - db_request.user = UserFactory.create() - - RoleFactory.create(project=project, user=db_request.user, role_name="Owner") - - settings_views = views.ManageProjectSettingsViews(project, db_request) - result = settings_views.delete_project_alternate_repository() - - assert isinstance(result, HTTPSeeOther) - assert result.headers["Location"] == "/the-redirect" - assert db_request.session.flash.calls == [ - pretend.call("Invalid alternate repository for project", queue="error") - ] - assert db_request.route_path.calls == [ - pretend.call("manage.project.settings", project_name="foo") - ] - - def test_delete_alternate_repository_no_confirm(self, db_request): - project = ProjectFactory.create(name="foo") - alt_repo = AlternateRepositoryFactory.create(project=project) - - db_request.POST = MultiDict( - { - "alternate_repository_id": str(alt_repo.id), - "alternate_repository_location": "delete", - } - ) - db_request.flags = pretend.stub(enabled=pretend.call_recorder(lambda *a: False)) - db_request.route_path = pretend.call_recorder(lambda *a, **kw: "/the-redirect") - db_request.session = pretend.stub( - flash=pretend.call_recorder(lambda *a, **kw: None) - ) - db_request.user = UserFactory.create() - - RoleFactory.create(project=project, user=db_request.user, role_name="Owner") - - settings_views = views.ManageProjectSettingsViews(project, db_request) - result = settings_views.delete_project_alternate_repository() - - assert isinstance(result, HTTPSeeOther) - assert result.headers["Location"] == "/the-redirect" - assert db_request.session.flash.calls == [ - pretend.call("Confirm the request", queue="error") - ] - assert db_request.route_path.calls == [ - pretend.call("manage.project.settings", project_name="foo") - ] - - def test_delete_alternate_repository_wrong_confirm(self, db_request): - project = ProjectFactory.create(name="foo") - alt_repo = AlternateRepositoryFactory.create(project=project) - - db_request.POST = MultiDict( - { - "alternate_repository_id": str(alt_repo.id), - "confirm_alternate_repository_name": f"invalid-confirm-{alt_repo.name}", - "alternate_repository_location": "delete", - } - ) - db_request.flags = pretend.stub(enabled=pretend.call_recorder(lambda *a: False)) - db_request.route_path = pretend.call_recorder(lambda *a, **kw: "/the-redirect") - db_request.session = pretend.stub( - flash=pretend.call_recorder(lambda *a, **kw: None) - ) - db_request.user = UserFactory.create() - - RoleFactory.create(project=project, user=db_request.user, role_name="Owner") - - settings_views = views.ManageProjectSettingsViews(project, db_request) - result = settings_views.delete_project_alternate_repository() - - assert isinstance(result, HTTPSeeOther) - assert result.headers["Location"] == "/the-redirect" - assert db_request.session.flash.calls == [ - pretend.call( - f"Could not delete alternate repository - " - f"invalid-confirm-{alt_repo.name} is not the same as {alt_repo.name}", - queue="error", - ) - ] - assert db_request.route_path.calls == [ - pretend.call("manage.project.settings", project_name="foo") - ] - def test_remove_organization_project_no_confirm(self): user = pretend.stub() project = pretend.stub( diff --git a/tests/unit/packaging/test_init.py b/tests/unit/packaging/test_init.py index 15f77e1baee9..b93b80f42133 100644 --- a/tests/unit/packaging/test_init.py +++ b/tests/unit/packaging/test_init.py @@ -14,7 +14,7 @@ IProjectService, ISimpleStorage, ) -from warehouse.packaging.models import AlternateRepository, File, Project, Release, Role +from warehouse.packaging.models import File, Project, Release, Role from warehouse.packaging.services import project_service_factory from warehouse.packaging.tasks import ( check_file_cache_tasks_outstanding, @@ -145,13 +145,6 @@ def key_factory(keystring, iterate_on=None, if_attr_exists=None): key_factory("project/{itr.normalized_name}", iterate_on="projects"), ], ), - pretend.call( - AlternateRepository, - cache_keys=["project/{obj.project.normalized_name}"], - purge_keys=[ - key_factory("project/{obj.project.normalized_name}"), - ], - ), pretend.call( OrganizationProject, purge_keys=[ diff --git a/warehouse/locale/messages.pot b/warehouse/locale/messages.pot index 82acab22cf5b..328f3c41d4fb 100644 --- a/warehouse/locale/messages.pot +++ b/warehouse/locale/messages.pot @@ -99,8 +99,7 @@ msgid "" "different email." msgstr "" -#: warehouse/accounts/forms.py:426 warehouse/manage/forms.py:132 -#: warehouse/manage/forms.py:824 +#: warehouse/accounts/forms.py:426 warehouse/manage/forms.py:131 msgid "The name is too long. Choose a name with 100 characters or less." msgstr "" @@ -164,7 +163,7 @@ msgstr "" msgid "Successful WebAuthn assertion" msgstr "" -#: warehouse/accounts/views.py:633 warehouse/manage/views/__init__.py:948 +#: warehouse/accounts/views.py:633 warehouse/manage/views/__init__.py:945 msgid "Recovery code accepted. The supplied code cannot be used again." msgstr "" @@ -404,31 +403,31 @@ msgstr "" msgid "Banner Preview" msgstr "" -#: warehouse/manage/forms.py:292 +#: warehouse/manage/forms.py:291 msgid "Specify an association ID" msgstr "" -#: warehouse/manage/forms.py:293 +#: warehouse/manage/forms.py:292 msgid "Association must be specified by ID" msgstr "" -#: warehouse/manage/forms.py:308 +#: warehouse/manage/forms.py:307 msgid "No account association with given ID" msgstr "" -#: warehouse/manage/forms.py:313 +#: warehouse/manage/forms.py:312 msgid "This association does not belong to you" msgstr "" -#: warehouse/manage/forms.py:417 +#: warehouse/manage/forms.py:416 msgid "Provide your response to the request." msgstr "" -#: warehouse/manage/forms.py:459 +#: warehouse/manage/forms.py:458 msgid "Choose an organization account name with 50 characters or less." msgstr "" -#: warehouse/manage/forms.py:467 +#: warehouse/manage/forms.py:466 msgid "" "The organization account name is invalid. Organization account names must" " be composed of letters, numbers, dots, hyphens and underscores. And must" @@ -436,242 +435,194 @@ msgid "" "organization account name." msgstr "" -#: warehouse/manage/forms.py:490 +#: warehouse/manage/forms.py:489 msgid "" "This organization account name has already been used. Choose a different " "organization account name." msgstr "" -#: warehouse/manage/forms.py:505 +#: warehouse/manage/forms.py:504 msgid "" "You have already submitted an application for that name. Choose a " "different organization account name." msgstr "" -#: warehouse/manage/forms.py:540 +#: warehouse/manage/forms.py:539 msgid "Select project" msgstr "" -#: warehouse/manage/forms.py:545 warehouse/oidc/forms/_core.py:36 +#: warehouse/manage/forms.py:544 warehouse/oidc/forms/_core.py:36 #: warehouse/oidc/forms/gitlab.py:54 msgid "Specify project name" msgstr "" -#: warehouse/manage/forms.py:549 +#: warehouse/manage/forms.py:548 msgid "" "Start and end with a letter or numeral containing only ASCII numeric and " "'.', '_' and '-'." msgstr "" -#: warehouse/manage/forms.py:556 +#: warehouse/manage/forms.py:555 msgid "This project name has already been used. Choose a different project name." msgstr "" -#: warehouse/manage/forms.py:589 +#: warehouse/manage/forms.py:588 msgid "Cannot transfer to Company Organization with inactive billing" msgstr "" -#: warehouse/manage/forms.py:642 +#: warehouse/manage/forms.py:641 msgid "" "The organization name is too long. Choose a organization name with 100 " "characters or less." msgstr "" -#: warehouse/manage/forms.py:654 +#: warehouse/manage/forms.py:653 msgid "" "The organization URL is too long. Choose a organization URL with 400 " "characters or less." msgstr "" -#: warehouse/manage/forms.py:660 +#: warehouse/manage/forms.py:659 msgid "The organization URL must start with http:// or https://" msgstr "" -#: warehouse/manage/forms.py:672 +#: warehouse/manage/forms.py:671 msgid "" "The organization description is too long. Choose a organization " "description with 400 characters or less." msgstr "" -#: warehouse/manage/forms.py:715 +#: warehouse/manage/forms.py:714 msgid "" "We don't need to know quite that much :), limit your usage description to" " 1024 characters or less." msgstr "" -#: warehouse/manage/forms.py:737 +#: warehouse/manage/forms.py:736 msgid "You have already submitted the maximum number of " msgstr "" -#: warehouse/manage/forms.py:766 +#: warehouse/manage/forms.py:765 msgid "Choose a team name with 50 characters or less." msgstr "" -#: warehouse/manage/forms.py:773 +#: warehouse/manage/forms.py:772 msgid "" "The team name is invalid. Team names cannot start or end with a space, " "period, underscore, hyphen, or slash. Choose a different team name." msgstr "" -#: warehouse/manage/forms.py:801 +#: warehouse/manage/forms.py:800 msgid "This team name has already been used. Choose a different team name." msgstr "" -#: warehouse/manage/forms.py:819 -msgid "Specify your alternate repository name" -msgstr "" - -#: warehouse/manage/forms.py:833 -msgid "Specify your alternate repository URL" -msgstr "" - -#: warehouse/manage/forms.py:838 -msgid "The URL is too long. Choose a URL with 400 characters or less." -msgstr "" - -#: warehouse/manage/forms.py:852 -msgid "" -"The description is too long. Choose a description with 400 characters or " -"less." -msgstr "" - -#: warehouse/manage/views/__init__.py:408 +#: warehouse/manage/views/__init__.py:405 msgid "Account details updated" msgstr "" -#: warehouse/manage/views/__init__.py:439 +#: warehouse/manage/views/__init__.py:436 #, python-brace-format msgid "Email ${email_address} added - check your email for a verification link" msgstr "" -#: warehouse/manage/views/__init__.py:895 +#: warehouse/manage/views/__init__.py:892 msgid "Recovery codes already generated" msgstr "" -#: warehouse/manage/views/__init__.py:897 +#: warehouse/manage/views/__init__.py:894 msgid "Generating new recovery codes will invalidate your existing codes." msgstr "" -#: warehouse/manage/views/__init__.py:1005 +#: warehouse/manage/views/__init__.py:1002 msgid "Verify your email to create an API token." msgstr "" -#: warehouse/manage/views/__init__.py:1107 +#: warehouse/manage/views/__init__.py:1104 msgid "API Token does not exist." msgstr "" -#: warehouse/manage/views/__init__.py:1139 +#: warehouse/manage/views/__init__.py:1136 msgid "Invalid credentials. Try again" msgstr "" -#: warehouse/manage/views/__init__.py:1258 -msgid "Invalid alternate repository location details" -msgstr "" - -#: warehouse/manage/views/__init__.py:1296 -#, python-brace-format -msgid "Added alternate repository '${name}'" -msgstr "" - -#: warehouse/manage/views/__init__.py:1329 -#: warehouse/manage/views/__init__.py:1590 -#: warehouse/manage/views/__init__.py:1675 -#: warehouse/manage/views/__init__.py:1776 -#: warehouse/manage/views/__init__.py:1876 -msgid "Confirm the request" -msgstr "" - -#: warehouse/manage/views/__init__.py:1341 -msgid "Invalid alternate repository id" -msgstr "" - -#: warehouse/manage/views/__init__.py:1352 -msgid "Invalid alternate repository for project" -msgstr "" - -#: warehouse/manage/views/__init__.py:1361 -#, python-brace-format -msgid "" -"Could not delete alternate repository - ${confirm} is not the same as " -"${alt_repo_name}" -msgstr "" - -#: warehouse/manage/views/__init__.py:1391 -#, python-brace-format -msgid "Deleted alternate repository '${name}'" -msgstr "" - -#: warehouse/manage/views/__init__.py:1459 -#: warehouse/manage/views/__init__.py:1760 -#: warehouse/manage/views/__init__.py:1868 +#: warehouse/manage/views/__init__.py:1302 +#: warehouse/manage/views/__init__.py:1603 +#: warehouse/manage/views/__init__.py:1711 msgid "" "Project deletion temporarily disabled. See https://pypi.org/help#admin-" "intervention for details." msgstr "" -#: warehouse/manage/views/__init__.py:1603 +#: warehouse/manage/views/__init__.py:1433 +#: warehouse/manage/views/__init__.py:1518 +#: warehouse/manage/views/__init__.py:1619 +#: warehouse/manage/views/__init__.py:1719 +msgid "Confirm the request" +msgstr "" + +#: warehouse/manage/views/__init__.py:1446 msgid "Could not yank release - " msgstr "" -#: warehouse/manage/views/__init__.py:1688 +#: warehouse/manage/views/__init__.py:1531 msgid "Could not un-yank release - " msgstr "" -#: warehouse/manage/views/__init__.py:1789 +#: warehouse/manage/views/__init__.py:1632 msgid "Could not delete release - " msgstr "" -#: warehouse/manage/views/__init__.py:1888 +#: warehouse/manage/views/__init__.py:1731 msgid "Could not find file" msgstr "" -#: warehouse/manage/views/__init__.py:1893 +#: warehouse/manage/views/__init__.py:1736 msgid "Could not delete file - " msgstr "" -#: warehouse/manage/views/__init__.py:2043 +#: warehouse/manage/views/__init__.py:1886 #, python-brace-format msgid "Team '${team_name}' already has ${role_name} role for project" msgstr "" -#: warehouse/manage/views/__init__.py:2150 +#: warehouse/manage/views/__init__.py:1993 #, python-brace-format msgid "User '${username}' already has ${role_name} role for project" msgstr "" -#: warehouse/manage/views/__init__.py:2217 +#: warehouse/manage/views/__init__.py:2060 #, python-brace-format msgid "${username} is now ${role} of the '${project_name}' project." msgstr "" -#: warehouse/manage/views/__init__.py:2249 +#: warehouse/manage/views/__init__.py:2092 #, python-brace-format msgid "" "User '${username}' does not have a verified primary email address and " "cannot be added as a ${role_name} for project" msgstr "" -#: warehouse/manage/views/__init__.py:2262 +#: warehouse/manage/views/__init__.py:2105 #: warehouse/manage/views/organizations.py:981 #, python-brace-format msgid "User '${username}' already has an active invite. Please try again later." msgstr "" -#: warehouse/manage/views/__init__.py:2327 +#: warehouse/manage/views/__init__.py:2170 #: warehouse/manage/views/organizations.py:1056 #, python-brace-format msgid "Invitation sent to '${username}'" msgstr "" -#: warehouse/manage/views/__init__.py:2359 +#: warehouse/manage/views/__init__.py:2202 msgid "Could not find role invitation." msgstr "" -#: warehouse/manage/views/__init__.py:2370 +#: warehouse/manage/views/__init__.py:2213 msgid "Invitation already expired." msgstr "" -#: warehouse/manage/views/__init__.py:2403 +#: warehouse/manage/views/__init__.py:2246 #: warehouse/manage/views/organizations.py:1256 #, python-brace-format msgid "Invitation revoked from '${username}'." @@ -1354,7 +1305,7 @@ msgstr "" #: warehouse/templates/manage/project/release.html:209 #: warehouse/templates/manage/project/settings.html:78 #: warehouse/templates/manage/project/settings.html:124 -#: warehouse/templates/manage/project/settings.html:365 +#: warehouse/templates/manage/project/settings.html:233 #: warehouse/templates/manage/team/settings.html:62 msgid "Warning" msgstr "" @@ -1746,9 +1697,6 @@ msgstr "" #: warehouse/templates/manage/project/roles.html:364 #: warehouse/templates/manage/project/roles.html:397 #: warehouse/templates/manage/project/roles.html:416 -#: warehouse/templates/manage/project/settings.html:269 -#: warehouse/templates/manage/project/settings.html:285 -#: warehouse/templates/manage/project/settings.html:301 #: warehouse/templates/manage/team/roles.html:104 #: warehouse/templates/manage/team/settings.html:22 #: warehouse/templates/packaging/submit-malware-observation.html:54 @@ -2080,9 +2028,6 @@ msgstr "" #: warehouse/templates/manage/project/history.html:295 #: warehouse/templates/manage/project/history.html:306 #: warehouse/templates/manage/project/history.html:317 -#: warehouse/templates/manage/project/settings.html:212 -#: warehouse/templates/manage/project/settings.html:267 -#: warehouse/templates/manage/project/settings.html:272 #: warehouse/templates/manage/unverified-account.html:119 msgid "Name" msgstr "" @@ -5037,7 +4982,7 @@ msgstr "" #: warehouse/templates/manage/account/publishing.html:24 #: warehouse/templates/manage/project/settings.html:97 #: warehouse/templates/manage/project/settings.html:171 -#: warehouse/templates/manage/project/settings.html:439 +#: warehouse/templates/manage/project/settings.html:307 msgid "Project Name" msgstr "" @@ -5157,7 +5102,6 @@ msgstr "" #: warehouse/templates/manage/project/publishing.html:276 #: warehouse/templates/manage/project/publishing.html:351 #: warehouse/templates/manage/project/roles.html:373 -#: warehouse/templates/manage/project/settings.html:322 #: warehouse/templates/manage/team/roles.html:125 msgid "Add" msgstr "" @@ -6408,7 +6352,6 @@ msgstr "" #: warehouse/templates/manage/organization/roles.html:352 #: warehouse/templates/manage/project/release.html:96 #: warehouse/templates/manage/project/releases.html:98 -#: warehouse/templates/manage/project/settings.html:239 msgid "Delete" msgstr "" @@ -6895,9 +6838,6 @@ msgstr "" #: warehouse/templates/manage/project/history.html:296 #: warehouse/templates/manage/project/history.html:307 #: warehouse/templates/manage/project/history.html:318 -#: warehouse/templates/manage/project/settings.html:213 -#: warehouse/templates/manage/project/settings.html:283 -#: warehouse/templates/manage/project/settings.html:288 msgid "Url" msgstr "" @@ -7606,70 +7546,12 @@ msgid "You are not an owner or manager of any organizations." msgstr "" #: warehouse/templates/manage/project/settings.html:195 -msgid "Alternate repository locations" -msgstr "" - -#: warehouse/templates/manage/project/settings.html:198 -#, python-format -msgid "" -"Provisional support for PEP 708 \"Alternate " -"Locations\" Metadata." -msgstr "" - -#: warehouse/templates/manage/project/settings.html:202 -#, python-format -msgid "" -"Implementation may change, consider subscribing to pypi-announce to be notified of " -"changes." -msgstr "" - -#: warehouse/templates/manage/project/settings.html:208 -#, python-format -msgid "Alternate repository locations for %(project_name)s" -msgstr "" - -#: warehouse/templates/manage/project/settings.html:214 -msgid "Description" -msgstr "" - -#: warehouse/templates/manage/project/settings.html:230 -#, python-format -msgid "Delete %(name)s from this project." -msgstr "" - -#: warehouse/templates/manage/project/settings.html:240 -msgid "Alternate Repository Name" -msgstr "" - -#: warehouse/templates/manage/project/settings.html:254 -msgid "There are no alternate repositories for this project, yet." -msgstr "" - -#: warehouse/templates/manage/project/settings.html:256 -msgid "Get started by adding an alternate repository below." -msgstr "" - -#: warehouse/templates/manage/project/settings.html:259 -msgid "Add alternate repository location" -msgstr "" - -#: warehouse/templates/manage/project/settings.html:299 -msgid "Alternate repository description" -msgstr "" - -#: warehouse/templates/manage/project/settings.html:304 -#: warehouse/templates/manage/project/settings.html:315 -msgid "Description of the purpose or content of the alternate repository." -msgstr "" - -#: warehouse/templates/manage/project/settings.html:327 -#: warehouse/templates/manage/project/settings.html:352 -#: warehouse/templates/manage/project/settings.html:356 +#: warehouse/templates/manage/project/settings.html:220 +#: warehouse/templates/manage/project/settings.html:224 msgid "Archive project" msgstr "" -#: warehouse/templates/manage/project/settings.html:331 +#: warehouse/templates/manage/project/settings.html:199 #, python-format msgid "" "Archiving a project will prevent any new uploads, and remove the project " @@ -7682,33 +7564,33 @@ msgid "" "description by editing the README file." msgstr "" -#: warehouse/templates/manage/project/settings.html:343 -#: warehouse/templates/manage/project/settings.html:346 +#: warehouse/templates/manage/project/settings.html:211 +#: warehouse/templates/manage/project/settings.html:214 msgid "Unarchive project" msgstr "" -#: warehouse/templates/manage/project/settings.html:347 +#: warehouse/templates/manage/project/settings.html:215 msgid "" "Unarchiving a project will allow new file uploads and add the project to " "the search index." msgstr "" -#: warehouse/templates/manage/project/settings.html:357 +#: warehouse/templates/manage/project/settings.html:225 msgid "" "Archiving a project will block any new file uploads and remove the " "project from the search index." msgstr "" -#: warehouse/templates/manage/project/settings.html:363 -#: warehouse/templates/manage/project/settings.html:439 +#: warehouse/templates/manage/project/settings.html:231 +#: warehouse/templates/manage/project/settings.html:307 msgid "Delete project" msgstr "" -#: warehouse/templates/manage/project/settings.html:366 +#: warehouse/templates/manage/project/settings.html:234 msgid "Deleting this project will:" msgstr "" -#: warehouse/templates/manage/project/settings.html:371 +#: warehouse/templates/manage/project/settings.html:239 #, python-format msgid "" "Irreversibly delete the project along with %(count)s" @@ -7719,15 +7601,15 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: warehouse/templates/manage/project/settings.html:377 +#: warehouse/templates/manage/project/settings.html:245 msgid "Irreversibly delete the project" msgstr "" -#: warehouse/templates/manage/project/settings.html:381 +#: warehouse/templates/manage/project/settings.html:249 msgid "Make the project name available to any other PyPI user" msgstr "" -#: warehouse/templates/manage/project/settings.html:384 +#: warehouse/templates/manage/project/settings.html:252 msgid "" "This user will be able to make new releases under this project name, so " "long as the distribution filenames do not match filenames from a " diff --git a/warehouse/manage/forms.py b/warehouse/manage/forms.py index 6467d8481e7c..1543e66cd082 100644 --- a/warehouse/manage/forms.py +++ b/warehouse/manage/forms.py @@ -7,7 +7,6 @@ import warehouse.utils.otp as otp import warehouse.utils.webauthn as webauthn -from warehouse import forms from warehouse.accounts.forms import ( NewEmailMixin, NewPasswordMixin, @@ -806,52 +805,3 @@ def validate_name(self, field): class CreateTeamForm(SaveTeamForm): __params__ = SaveTeamForm.__params__ - - -class AddAlternateRepositoryForm(wtforms.Form): - """Form to add an Alternate Repository Location for a Project.""" - - __params__ = ["display_name", "link_url", "description"] - - display_name = wtforms.StringField( - validators=[ - wtforms.validators.InputRequired( - message=_("Specify your alternate repository name"), - ), - wtforms.validators.Length( - max=100, - message=_( - "The name is too long. " - "Choose a name with 100 characters or less." - ), - ), - ] - ) - link_url = wtforms.URLField( - validators=[ - wtforms.validators.InputRequired( - message=_("Specify your alternate repository URL"), - ), - wtforms.validators.Length( - max=400, - message=_( - "The URL is too long. Choose a URL with 400 characters or less." - ), - ), - forms.URIValidator(), - ] - ) - description = wtforms.TextAreaField( - validators=[ - wtforms.validators.InputRequired( - message="Describe the purpose and content of the alternate repository." - ), - wtforms.validators.Length( - max=400, - message=_( - "The description is too long. " - "Choose a description with 400 characters or less." - ), - ), - ] - ) diff --git a/warehouse/manage/views/__init__.py b/warehouse/manage/views/__init__.py index 706323aa8ee7..3bb0c2d40a7a 100644 --- a/warehouse/manage/views/__init__.py +++ b/warehouse/manage/views/__init__.py @@ -2,7 +2,6 @@ import base64 import io -import uuid import pyqrcode @@ -62,7 +61,6 @@ from warehouse.macaroons import caveats from warehouse.macaroons.interfaces import IMacaroonService from warehouse.manage.forms import ( - AddAlternateRepositoryForm, AddEmailForm, ChangePasswordForm, ChangeRoleForm, @@ -99,7 +97,6 @@ TeamRole, ) from warehouse.packaging.models import ( - AlternateRepository, File, JournalEntry, Project, @@ -1202,7 +1199,6 @@ def __init__(self, project, request): self.project = project self.request = request self.transfer_organization_project_form_class = TransferOrganizationProjectForm - self.add_alternate_repository_form_class = AddAlternateRepositoryForm @view_config(request_method="GET") def manage_project_settings(self): @@ -1243,159 +1239,6 @@ def manage_project_settings(self): "add_alternate_repository_form_class": add_alt_repo_form, } - @view_config( - request_method="POST", - request_param=AddAlternateRepositoryForm.__params__ - + ["alternate_repository_location=add"], - require_reauth=True, - permission=Permissions.ProjectsWrite, - ) - def add_project_alternate_repository(self): - form = self.add_alternate_repository_form_class(self.request.POST) - - if not form.validate(): - self.request.session.flash( - self.request._("Invalid alternate repository location details"), - queue="error", - ) - return HTTPSeeOther( - self.request.route_path( - "manage.project.settings", - project_name=self.project.name, - ) - ) - - # add the alternate repository location entry - alt_repo = AlternateRepository( - project=self.project, - name=form.display_name.data, - url=form.link_url.data, - description=form.description.data, - ) - self.request.db.add(alt_repo) - self.project.record_event( - tag=EventTag.Project.AlternateRepositoryAdd, - request=self.request, - additional={ - "added_by": self.request.user.username, - "display_name": alt_repo.name, - "link_url": alt_repo.url, - }, - ) - self.request.user.record_event( - tag=EventTag.Account.AlternateRepositoryAdd, - request=self.request, - additional={ - "added_by": self.request.user.username, - "display_name": alt_repo.name, - "link_url": alt_repo.url, - }, - ) - self.request.session.flash( - self.request._( - "Added alternate repository '${name}'", - mapping={"name": alt_repo.name}, - ), - queue="success", - ) - - return HTTPSeeOther( - self.request.route_path( - "manage.project.settings", - project_name=self.project.name, - ) - ) - - @view_config( - request_method="POST", - request_param=[ - "alternate_repository_id", - "alternate_repository_location=delete", - ], - require_reauth=True, - permission=Permissions.ProjectsWrite, - ) - def delete_project_alternate_repository(self): - confirm_name = self.request.POST.get("confirm_alternate_repository_name") - resp_inst = HTTPSeeOther( - self.request.route_path( - "manage.project.settings", project_name=self.project.name - ) - ) - - # Must confirm alt repo name to delete. - if not confirm_name: - self.request.session.flash( - self.request._("Confirm the request"), queue="error" - ) - return resp_inst - - # Must provide a valid alt repo id. - alternate_repository_id = self.request.POST.get("alternate_repository_id", "") - try: - uuid.UUID(str(alternate_repository_id)) - except ValueError: - alternate_repository_id = None - if not alternate_repository_id: - self.request.session.flash( - self.request._("Invalid alternate repository id"), - queue="error", - ) - return resp_inst - - # The provided alt repo id must be related to this project. - alt_repo: AlternateRepository = self.request.db.get( - AlternateRepository, alternate_repository_id - ) - if not alt_repo or alt_repo not in self.project.alternate_repositories: - self.request.session.flash( - self.request._("Invalid alternate repository for project"), - queue="error", - ) - return resp_inst - - # The confirmed alt repo name must match the provided alt repo id. - if confirm_name != alt_repo.name: - self.request.session.flash( - self.request._( - "Could not delete alternate repository - " - "${confirm} is not the same as ${alt_repo_name}", - mapping={"confirm": confirm_name, "alt_repo_name": alt_repo.name}, - ), - queue="error", - ) - return resp_inst - - # delete the alternate repository location entry - self.request.db.delete(alt_repo) - self.project.record_event( - tag=EventTag.Project.AlternateRepositoryDelete, - request=self.request, - additional={ - "deleted_by": self.request.user.username, - "display_name": alt_repo.name, - "link_url": alt_repo.url, - }, - ) - self.request.user.record_event( - tag=EventTag.Account.AlternateRepositoryDelete, - request=self.request, - additional={ - "deleted_by": self.request.user.username, - "display_name": alt_repo.name, - "link_url": alt_repo.url, - }, - ) - self.request.session.flash( - self.request._( - "Deleted alternate repository '${name}'", - mapping={"name": alt_repo.name}, - ), - queue="success", - ) - - return resp_inst - def get_user_role_in_project(project, user, request): try: diff --git a/warehouse/packaging/__init__.py b/warehouse/packaging/__init__.py index d2e97723a6eb..d6873fdfcdcd 100644 --- a/warehouse/packaging/__init__.py +++ b/warehouse/packaging/__init__.py @@ -14,7 +14,7 @@ IProjectService, ISimpleStorage, ) -from warehouse.packaging.models import AlternateRepository, File, Project, Release, Role +from warehouse.packaging.models import File, Project, Release, Role from warehouse.packaging.services import project_service_factory from warehouse.packaging.tasks import ( check_file_cache_tasks_outstanding, @@ -162,13 +162,6 @@ def includeme(config): key_factory("project/{itr.normalized_name}", iterate_on="projects"), ], ) - config.register_origin_cache_keys( - AlternateRepository, - cache_keys=["project/{obj.project.normalized_name}"], - purge_keys=[ - key_factory("project/{obj.project.normalized_name}"), - ], - ) config.register_origin_cache_keys( OrganizationProject, purge_keys=[ diff --git a/warehouse/packaging/models.py b/warehouse/packaging/models.py index 4b3d1f793c5d..df7b9521c462 100644 --- a/warehouse/packaging/models.py +++ b/warehouse/packaging/models.py @@ -245,11 +245,6 @@ class Project(SitemapMixin, HasEvents, HasObservations, db.Model): order_by=lambda: Release._pypi_ordering.desc(), passive_deletes=True, ) - alternate_repositories: Mapped[list[AlternateRepository]] = orm.relationship( - cascade="all, delete-orphan", - back_populates="project", - passive_deletes=True, - ) __table_args__ = ( CheckConstraint( @@ -1207,37 +1202,6 @@ class ProjectMacaroonWarningAssociation(db.Model): ) -class AlternateRepository(db.Model): - """ - Store an alternate repository name, url, description for a project. - One project can have zero, one, or more alternate repositories. - - For each project, ensures the url and name are unique. - Urls must start with http(s). - """ - - __tablename__ = "alternate_repositories" - __table_args__ = ( - UniqueConstraint("project_id", "url"), - UniqueConstraint("project_id", "name"), - CheckConstraint( - "url ~* '^https?://.+'::text", - name="alternate_repository_valid_url", - ), - ) - - __repr__ = make_repr("name", "url") - - project_id: Mapped[UUID] = mapped_column( - ForeignKey("projects.id", onupdate="CASCADE", ondelete="CASCADE"), - ) - project: Mapped[Project] = orm.relationship(back_populates="alternate_repositories") - - name: Mapped[str] - url: Mapped[str] - description: Mapped[str] - - @event.listens_for(File, "after_insert") def add_filename_to_registry(mapper, connection, target): """ diff --git a/warehouse/packaging/utils.py b/warehouse/packaging/utils.py index c37b8b7c1837..20ca4fddd95b 100644 --- a/warehouse/packaging/utils.py +++ b/warehouse/packaging/utils.py @@ -66,9 +66,6 @@ def _simple_detail(project, request): versions = sorted( {f.release.version for f in files}, key=packaging_legacy.version.parse ) - alternate_repositories = sorted( - alt_repo.url for alt_repo in project.alternate_repositories - ) return { "meta": {"api-version": API_VERSION, "_last-serial": project.last_serial}, @@ -79,7 +76,6 @@ def _simple_detail(project, request): } ), "versions": versions, - "alternate-locations": alternate_repositories, "files": [ { "filename": file.filename, @@ -171,5 +167,4 @@ def render_simple_detail(project, request, store=False): def _valid_simple_detail_context(context: dict) -> dict: context["project_status"] = context.pop("project-status", None) - context["alternate_locations"] = context.pop("alternate-locations", []) return context diff --git a/warehouse/templates/api/simple/detail.html b/warehouse/templates/api/simple/detail.html index 0febe7c4e26e..0ea186094384 100644 --- a/warehouse/templates/api/simple/detail.html +++ b/warehouse/templates/api/simple/detail.html @@ -3,7 +3,6 @@ - {% for alt_repo in alternate_locations %}{% endfor %} {% if project_status %}{% endif %} Links for {{ name }} diff --git a/warehouse/templates/manage/project/settings.html b/warehouse/templates/manage/project/settings.html index 11cf208dd449..8cdb05576b3d 100644 --- a/warehouse/templates/manage/project/settings.html +++ b/warehouse/templates/manage/project/settings.html @@ -192,138 +192,6 @@

{% endif %}
{% endif %} -

{% trans %}Alternate repository locations{% endtrans %}

-
-

- {% trans pep_url="https://peps.python.org/pep-0708/#alternate-locations-metadata" - %}Provisional support for PEP 708 "Alternate Locations" Metadata. {% endtrans %} -

-

- {% trans pypi_announce_url="https://mail.python.org/mailman3/lists/pypi-announce.python.org/" - %}Implementation may change, consider subscribing to pypi-announce to be notified of changes.{% endtrans %} -

-
-{% if project.alternate_repositories %} - - - - - - - - - - - - {% for alternate_repository in project.alternate_repositories|sort(attribute="name") %} - - - - - - - {% endfor %} - -
{% trans project_name=project.name %}Alternate repository locations for - {{ project_name }}{% endtrans %}
{% trans %}Name{% endtrans %}{% trans %}Url{% endtrans %}{% trans %}Description{% endtrans %}
{{ alternate_repository.name }} - {{ alternate_repository.url }} - {{ alternate_repository.description }} - {% set extra_description %} - {% trans name=alternate_repository.name %}Delete {{ name }} from this - project.{% endtrans %} - {% endset %} - {% set extra_fields %} - - - {% endset %} - {{ confirm_button(gettext("Delete") , - gettext("Alternate Repository Name"), - "alternate_repository_name", - alternate_repository.name, - extra_description=extra_description, - action=request.route_path('manage.project.settings', project_name=project.name), - extra_fields=extra_fields, - tooltip=extra_description - ) }} -
-{% else %} -

{% trans %}There are no alternate repositories for this project, yet.{% endtrans %}

- {% if request.has_permission(Permissions.ProjectsWrite) %} -

{% trans %}Get started by adding an alternate repository below.{% endtrans %}

- {% endif %} -{% endif %} -

{% trans %}Add alternate repository location{% endtrans %}

-
-
- - - - {{ add_alternate_repository_form_class.display_name(placeholder=gettext("Name") , - autocomplete="on", - autocapitalize="on", - spellcheck="true", - class_="form-group__field", - aria_describedby="alternate-repository-name-errors", - ) }} -
{{ field_errors(add_alternate_repository_form_class.display_name) }}
-
-
- - {{ add_alternate_repository_form_class.link_url(placeholder=gettext("Url") , - autocomplete="off", - autocapitalize="off", - spellcheck="false", - class_="form-group__field", - aria_describedby="alternate-repository-url-errors", - ) }} -
{{ field_errors(add_alternate_repository_form_class.link_url) }}
-
-
- - {{ add_alternate_repository_form_class.description(placeholder=gettext("Description of the purpose or content of the alternate repository.") , - autocomplete="off", - autocapitalize="off", - spellcheck="true", - class_="form-group__field", - aria_describedby="alternate-repository-description-errors", - ) }} -
- {{ field_errors(add_alternate_repository_form_class.description) }} -
-

- {% trans %} - Description of the purpose or content of the alternate repository. - {% endtrans %} -

-
-
- -
-
-

{% trans %}Archive project{% endtrans %}