Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to support django 5 #222

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python: [3.6]
python: [3.10.15]

steps:
- uses: actions/checkout@v2
Expand All @@ -17,7 +17,7 @@ jobs:
with:
python-version: ${{ matrix.python }}
- name: Install tox
run: pip install --upgrade setuptools tox==3.15.0
run: pip install --upgrade setuptools tox
- name: Run tests
run: tox -e py
- name: Upload coverage to Codecov
Expand Down
62 changes: 28 additions & 34 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,44 @@
readme = fh.readlines()

tests_require = [
'django-webtest==1.9.7',
'factory-boy==2.12.0',
'mock==4.0.2',
'pytest-cov==2.9.0',
'pytest-django==3.9.0',
'pytest==5.4.3',
'requests-mock==1.8.0',
'requests-toolbelt==0.9.1',
'django-webtest',
'factory-boy',
'mock',
'pytest-cov',
'pytest-django',
'pytest',
'requests-mock',
'requests-toolbelt',
]

setup(
name='localshop',
version='2.0.0-alpha.1',
version='3.0.0-alpha.1',
author='Michael van Tellingen',
author_email='[email protected]',
url='http://github.com/mvantellingen/localshop',
description='A private pypi server including auto-mirroring of pypi.',
long_description='\n'.join(readme),
zip_safe=False,
install_requires=[
'boto3==1.14.1',
'celery==4.4.0',
'django-braces==1.14.0',
'django-celery-beat==2.0.0',
'django-celery-results==1.2.1',
'django-environ==0.4.5',
'django-model-utils==4.0.0',
'django-storages==1.9.1',
'django-widget-tweaks==1.4.8',
'Django==2.2.13',
'docutils==0.15.2',
'netaddr==0.7.19',
'Pillow==7.1.2',
'psycopg2-binary==2.8.5',
'redis==3.5.3',
'requests==2.23.0',
'social-auth-app-django==3.4.0',
'sqlparse==0.3.1',
'boto3',
'celery',
'django-braces',
'django-celery-beat',
'django-celery-results',
'django-environ',
'django-model-utils',
'django-storages',
'django-widget-tweaks',
'Django',
'docutils',
'netaddr',
'Pillow',
'psycopg2-binary',
'redis',
'requests',
'social-auth-app-django',
'sqlparse',
'Versio==0.4.0',
],
tests_require=tests_require,
Expand All @@ -65,13 +65,7 @@
'Topic :: Software Development',
'Topic :: System',
'Topic :: System :: Software Distribution',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.10',
],
)
21 changes: 10 additions & 11 deletions src/localshop/apps/accounts/auth_urls.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
from django.conf import settings
from django.conf.urls import url
from django.contrib.auth.views import PasswordResetView, PasswordResetDoneView, PasswordChangeDoneView, \
PasswordChangeView, PasswordResetConfirmView, PasswordResetCompleteView, LogoutView
from django.urls import reverse_lazy
from django.urls import reverse_lazy, path, re_path
from django.views.generic.base import RedirectView

from localshop.apps.accounts.views import login as login_view

urlpatterns = [
url(r'^logout/$', LogoutView.as_view(), name='logout'),
url(r'^password_change/$', PasswordChangeView.as_view(), name='password_change'),
url(r'^password_change/done/$', PasswordChangeDoneView.as_view(), name='password_change_done'),
url(r'^password_reset/$', PasswordResetView.as_view(), name='password_reset'),
url(r'^password_reset/done/$', PasswordResetDoneView.as_view(), name='password_reset_done'),
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
path('logout/', LogoutView.as_view(), name='logout'),
path('password_change/', PasswordChangeView.as_view(), name='password_change'),
path('password_change/done/', PasswordChangeDoneView.as_view(), name='password_change_done'),
path('password_reset/', PasswordResetView.as_view(), name='password_reset'),
path('password_reset/done/', PasswordResetDoneView.as_view(), name='password_reset_done'),
re_path(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
url(r'^reset/done/$', PasswordResetCompleteView.as_view(), name='password_reset_complete'),
path('reset/done/', PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]

if settings.OAUTH2_PROVIDER:
urlpatterns.append(
url(r'^login/$', RedirectView.as_view(
path('login/', RedirectView.as_view(
url=reverse_lazy('social:begin', kwargs={
'backend': settings.OAUTH2_PROVIDER
}),
), name='login')
)
else:
urlpatterns.append(url(r'^login/$', login_view, name='login'))
urlpatterns.append(path('login/', login_view, name='login'))
4 changes: 1 addition & 3 deletions src/localshop/apps/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
from django.contrib.auth.models import AbstractUser
from django.urls import reverse
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from model_utils.fields import AutoCreatedField
from model_utils.models import TimeStampedModel

Expand Down Expand Up @@ -54,7 +53,6 @@ def allow_upload(self):
return True


@python_2_unicode_compatible
class Team(TimeStampedModel):
name = models.CharField(max_length=200)
description = models.CharField(max_length=500, blank=True)
Expand Down
32 changes: 16 additions & 16 deletions src/localshop/apps/accounts/urls.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
from django.conf.urls import include, url
from django.urls import path, include, re_path

from localshop.apps.accounts import views

app_name = 'accounts'

urlpatterns = [
url(r'^profile/$', views.ProfileView.as_view(), name='profile'),
url(r'^access-keys/$', views.AccessKeyListView.as_view(), name='access_key_list'),
url(r'^access-keys/new$', views.AccessKeyCreateView.as_view(), name='access_key_create'),
url(r'^access-keys/(?P<pk>\d+)/', include([
url(r'^secret$', views.AccessKeySecretView.as_view(), name='access_key_secret'),
url(r'^edit$', views.AccessKeyUpdateView.as_view(), name='access_key_edit'),
url(r'^delete$', views.AccessKeyDeleteView.as_view(), name='access_key_delete'),
path('profile/', views.ProfileView.as_view(), name='profile'),
path('access-keys/', views.AccessKeyListView.as_view(), name='access_key_list'),
path('access-keys/new', views.AccessKeyCreateView.as_view(), name='access_key_create'),
re_path(r'^access-keys/(?P<pk>\d+)/', include([
path('secret', views.AccessKeySecretView.as_view(), name='access_key_secret'),
path('edit', views.AccessKeyUpdateView.as_view(), name='access_key_edit'),
path('delete', views.AccessKeyDeleteView.as_view(), name='access_key_delete'),
])),

url(r'^teams/$', views.TeamListView.as_view(), name='team_list'),
url(r'^teams/create$', views.TeamCreateView.as_view(), name='team_create'),
url(r'^teams/(?P<pk>\d+)/', include([
url(r'^$', views.TeamDetailView.as_view(), name='team_detail'),
url(r'^edit$', views.TeamUpdateView.as_view(), name='team_edit'),
url(r'^delete$', views.TeamDeleteView.as_view(), name='team_delete'),
url(r'^member-add$', views.TeamMemberAddView.as_view(), name='team_member_add'),
url(r'^member-remove$', views.TeamMemberRemoveView.as_view(), name='team_member_remove'),
path('teams/', views.TeamListView.as_view(), name='team_list'),
path('teams/create', views.TeamCreateView.as_view(), name='team_create'),
re_path(r'^teams/(?P<pk>\d+)/', include([
path('', views.TeamDetailView.as_view(), name='team_detail'),
path('edit', views.TeamUpdateView.as_view(), name='team_edit'),
path('delete', views.TeamDeleteView.as_view(), name='team_delete'),
path('member-add', views.TeamMemberAddView.as_view(), name='team_member_add'),
path('member-remove', views.TeamMemberRemoveView.as_view(), name='team_member_remove'),
]))
]
6 changes: 3 additions & 3 deletions src/localshop/apps/accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, resolve_url
from django.template.response import TemplateResponse
from django.utils.http import is_safe_url
from django.utils.http import url_has_allowed_host_and_scheme
from django.views import generic
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect
Expand Down Expand Up @@ -146,7 +146,7 @@ def get_queryset(self):
return self.request.user.access_keys.all()

def get(self, request, pk, *args, **kwargs):
if not request.is_ajax():
if not request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest':
raise SuspiciousOperation
key = get_object_or_404(self.request.user.access_keys, pk=pk)
return HttpResponse(key.secret_key)
Expand Down Expand Up @@ -199,7 +199,7 @@ def login(request, template_name='registration/login.html',
if form.is_valid():

# Ensure the user-originating redirection url is safe.
if not is_safe_url(url=redirect_to, allowed_hosts=request.get_host()):
if not url_has_allowed_host_and_scheme(url=redirect_to, allowed_hosts=request.get_host()):
redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)

if not form.cleaned_data['remember_me']:
Expand Down
48 changes: 24 additions & 24 deletions src/localshop/apps/dashboard/urls.py
Original file line number Diff line number Diff line change
@@ -1,67 +1,67 @@
from django.conf.urls import include, url
from django.urls import path, include, re_path

from localshop.apps.dashboard import views

app_name = 'dashboard'

repository_urls = [
# Package urls
url(r'^packages/add/$',
path('packages/add/',
views.PackageAddView.as_view(),
name='package_add'),
url(r'^packages/(?P<name>[-._\w]+)/', include([
url(r'^$',
re_path(r'^packages/(?P<name>[-._\w]+)/', include([
path('',
views.PackageDetailView.as_view(),
name='package_detail'),
url(r'^refresh-from-upstream/$',
path('refresh-from-upstream/',
views.PackageRefreshView.as_view(),
name='package_refresh'),
url(r'^release-mirror-file/$',
path('release-mirror-file/',
views.PackageMirrorFileView.as_view(),
name='package_mirror_file'),
])),

# CIDR
url(r'^settings/cidr/$',
path('settings/cidr/',
views.CidrListView.as_view(), name='cidr_index'),
url(r'^settings/cidr/create$',
path('settings/cidr/create',
views.CidrCreateView.as_view(), name='cidr_create'),
url(r'^settings/cidr/(?P<pk>\d+)/edit',
re_path(r'^settings/cidr/(?P<pk>\d+)/edit',
views.CidrUpdateView.as_view(), name='cidr_edit'),
url(r'^settings/cidr/(?P<pk>\d+)/delete',
re_path(r'^settings/cidr/(?P<pk>\d+)/delete',
views.CidrDeleteView.as_view(), name='cidr_delete'),

# Credentials
url(r'^settings/credentials/$',
path('settings/credentials/',
views.CredentialListView.as_view(),
name='credential_index'),
url(r'^settings/credentials/create$',
path('settings/credentials/create',
views.CredentialCreateView.as_view(),
name='credential_create'),
url(r'^settings/credentials/(?P<access_key>[-a-f0-9]+)/secret',
re_path(r'^settings/credentials/(?P<access_key>[-a-f0-9]+)/secret',
views.CredentialSecretKeyView.as_view(),
name='credential_secret'),
url(r'^settings/credentials/(?P<access_key>[-a-f0-9]+)/edit',
re_path(r'^settings/credentials/(?P<access_key>[-a-f0-9]+)/edit',
views.CredentialUpdateView.as_view(),
name='credential_edit'),
url(r'^settings/credentials/(?P<access_key>[-a-f0-9]+)/delete',
re_path(r'^settings/credentials/(?P<access_key>[-a-f0-9]+)/delete',
views.CredentialDeleteView.as_view(),
name='credential_delete'),

url(r'^settings/teams/$', views.TeamAccessView.as_view(), name='team_access'),
path('settings/teams/', views.TeamAccessView.as_view(), name='team_access'),
]

urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^repositories/create$', views.RepositoryCreateView.as_view(), name='repository_create'),
path('', views.IndexView.as_view(), name='index'),
path('repositories/create', views.RepositoryCreateView.as_view(), name='repository_create'),

url(r'^repositories/(?P<slug>[^/]+)/', include([
url(r'^$', views.RepositoryDetailView.as_view(), name='repository_detail'),
url(r'^edit$', views.RepositoryUpdateView.as_view(), name='repository_edit'),
url(r'^delete$', views.RepositoryDeleteView.as_view(), name='repository_delete'),
url(r'^refresh$', views.RepositoryRefreshView.as_view(), name='repository_refresh'),
re_path(r'^repositories/(?P<slug>[^/]+)/', include([
path('', views.RepositoryDetailView.as_view(), name='repository_detail'),
path('edit', views.RepositoryUpdateView.as_view(), name='repository_edit'),
path('delete', views.RepositoryDeleteView.as_view(), name='repository_delete'),
path('refresh', views.RepositoryRefreshView.as_view(), name='repository_refresh'),
])),

url(r'^repositories/(?P<repo>[^/]+)/', include(repository_urls))
re_path(r'^repositories/(?P<repo>[^/]+)/', include(repository_urls))

]
2 changes: 1 addition & 1 deletion src/localshop/apps/dashboard/views/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def get_success_url(self):
class CredentialSecretKeyView(RepositoryMixin, generic.View):

def get(self, request, repo, access_key):
if not request.is_ajax():
if not request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest':
raise SuspiciousOperation
credential = get_object_or_404(
self.repository.credentials, access_key=access_key)
Expand Down
2 changes: 1 addition & 1 deletion src/localshop/apps/packages/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from django.db import models
from django.db.models.signals import post_delete
from django.utils.html import escape
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from docutils.utils import SystemMessage
from model_utils import Choices
from model_utils.fields import AutoCreatedField, AutoLastModifiedField
Expand Down
12 changes: 7 additions & 5 deletions src/localshop/apps/packages/tasks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import logging
import mimetypes
import os

Expand Down Expand Up @@ -99,8 +98,8 @@ def fetch_package(repository_pk, slug):
logger.info('done fetch_package: %s', slug)


@app.task(ignore_result=True)
def download_file(pk):
@app.task(bind=True, ignore_result=True)
def download_file(self, pk):
"""Download the file reference in `models.ReleaseFile` with the given pk.

"""
Expand All @@ -110,8 +109,11 @@ def download_file(pk):
proxies = None
if settings.LOCALSHOP_HTTP_PROXY:
proxies = settings.LOCALSHOP_HTTP_PROXY
response = requests.get(release_file.url, stream=True, proxies=proxies)

try:
response = requests.get(release_file.url, stream=True, proxies=proxies)
response.raise_for_status()
except requests.exceptions.RequestException as e:
raise self.retry(exc=e)
# Write the file to the django file field
filename = os.path.basename(release_file.url)

Expand Down
8 changes: 4 additions & 4 deletions src/localshop/apps/packages/urls.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
from django.conf.urls import url
from django.urls import re_path
from django.views.decorators.cache import cache_page

from localshop.apps.packages import views

app_name = 'packages'

urlpatterns = [
url(r'^(?P<repo>[-._\w]+)/?$', views.SimpleIndex.as_view(),
re_path(r'^(?P<repo>[-._\w]+)/?$', views.SimpleIndex.as_view(),
name='simple_index'),

url(r'^(?P<repo>[-._\w]+)/(?P<slug>[-._\w]+)/$',
re_path(r'^(?P<repo>[-._\w]+)/(?P<slug>[-._\w]+)/$',
cache_page(60)(views.SimpleDetail.as_view()),
name='simple_detail'),

url(r'^(?P<repo>[-._\w]+)/download/(?P<name>[-._\w]+)/(?P<pk>\d+)/(?P<filename>.*)$',
re_path(r'^(?P<repo>[-._\w]+)/download/(?P<name>[-._\w]+)/(?P<pk>\d+)/(?P<filename>.*)$',
views.DownloadReleaseFile.as_view(), name='download'),
]
Loading
Loading