diff --git a/PDMI/PDMI/settings.py b/PDMI/PDMI/settings.py index b1564b1..6c8c193 100644 --- a/PDMI/PDMI/settings.py +++ b/PDMI/PDMI/settings.py @@ -41,6 +41,7 @@ INSTALLED_APPS = [ 'store', 'doc', 'front', + 'api', 'bootstrap_modal_forms', 'widget_tweaks', 'markdownx', diff --git a/PDMI/PDMI/urls.py b/PDMI/PDMI/urls.py index 2e0e0a3..97aa087 100644 --- a/PDMI/PDMI/urls.py +++ b/PDMI/PDMI/urls.py @@ -15,7 +15,7 @@ Including another URLconf """ from django.contrib import admin from django.urls import path, include -import store, front, doc +import store, front, doc, api urlpatterns = [ path('admin/', admin.site.urls), @@ -24,4 +24,5 @@ urlpatterns = [ path('store/', include('store.urls'), name='store'), path('doc/', include('doc.urls'), name='doc'), path('markdownx/', include('markdownx.urls')), + path('api/', include('api.urls')), ] diff --git a/PDMI/api/__init__.py b/PDMI/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/PDMI/api/admin.py b/PDMI/api/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/PDMI/api/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/PDMI/api/apps.py b/PDMI/api/apps.py new file mode 100644 index 0000000..d87006d --- /dev/null +++ b/PDMI/api/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + name = 'api' diff --git a/PDMI/api/migrations/__init__.py b/PDMI/api/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/PDMI/api/models.py b/PDMI/api/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/PDMI/api/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/PDMI/api/tests.py b/PDMI/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/PDMI/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/PDMI/api/urls.py b/PDMI/api/urls.py new file mode 100644 index 0000000..4d10656 --- /dev/null +++ b/PDMI/api/urls.py @@ -0,0 +1,21 @@ +"""PDMI URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.urls import path +from . import views + +urlpatterns = [ + path('download///', views.ModuleDownloadView.as_view(), name="api_dl") +] diff --git a/PDMI/api/views.py b/PDMI/api/views.py new file mode 100644 index 0000000..de59124 --- /dev/null +++ b/PDMI/api/views.py @@ -0,0 +1,16 @@ +from django.shortcuts import render +from django.views import View +from django.http import HttpResponse, JsonResponse +from store.models import Module, Version +from django.shortcuts import get_object_or_404 +from io import BytesIO +import zipfile, os + +class ModuleDownloadView(View): + def get(self, request, req_mod, req_ver): + module = get_object_or_404(Module, name=req_mod) + version = get_object_or_404(Version, module=module, ver=req_ver) + zf = open(version.file.path, 'rb') + response = HttpResponse(zf, content_type="application/force-download") + response['Content-Disposition'] = f'attachment; filename={module.name}-{version.ver}.zip' + return response diff --git a/PDMI/store/response.py b/PDMI/store/response.py deleted file mode 100644 index b4b0065..0000000 --- a/PDMI/store/response.py +++ /dev/null @@ -1,32 +0,0 @@ -# encoding: utf-8 -from django.http import HttpResponse -import json - -MIMEANY = '*/*' -MIMEJSON = 'application/json' -MIMETEXT = 'text/plain' - - -def response_mimetype(request): - """response_mimetype -- Return a proper response mimetype, accordingly to - what the client accepts, as available in the `HTTP_ACCEPT` header. - request -- a HttpRequest instance. - """ - can_json = MIMEJSON in request.META['HTTP_ACCEPT'] - can_json |= MIMEANY in request.META['HTTP_ACCEPT'] - return MIMEJSON if can_json else MIMETEXT - - -class JsonResponse(HttpResponse): - """JSONResponse -- Extends HTTPResponse to handle JSON format response. - This response can be used in any view that should return a json stream of - data. - Usage: - def a_iew(request): - content = {'key': 'value'} - return JSONResponse(content, mimetype=response_mimetype(request)) - """ - def __init__(self, obj='', json_opts=None, mimetype=MIMEJSON, *args, **kwargs): - json_opts = json_opts if isinstance(json_opts, dict) else {} - content = json.dumps(obj, **json_opts) - super(JsonResponse, self).__init__(content, mimetype, *args, **kwargs) diff --git a/PDMI/store/templates/store/module_detail.html b/PDMI/store/templates/store/module_detail.html index 725db10..9c44323 100644 --- a/PDMI/store/templates/store/module_detail.html +++ b/PDMI/store/templates/store/module_detail.html @@ -40,9 +40,9 @@

- +

Module by {{ module.creator }} diff --git a/PDMI/store/views.py b/PDMI/store/views.py index 8f9f3d2..66578eb 100644 --- a/PDMI/store/views.py +++ b/PDMI/store/views.py @@ -9,11 +9,10 @@ from django.views.generic.list import ListView from django.views.generic.detail import DetailView from django.views import View from .forms import FileFieldForm -from .response import response_mimetype, JsonResponse from .models import Module, Version, Dependency from PDMI import settings from packaging.specifiers import SpecifierSet -from django.http import HttpResponse +from django.http import HttpResponse, JsonResponse from django.utils import timezone from markdownx.utils import markdownify import os