aboutsummaryrefslogtreecommitdiffstats
path: root/pyblackbird_cc
diff options
context:
space:
mode:
Diffstat (limited to 'pyblackbird_cc')
-rw-r--r--pyblackbird_cc/payments/tests/test_models.py8
-rw-r--r--pyblackbird_cc/payments/views.py9
-rw-r--r--pyblackbird_cc/resources/admin.py7
-rw-r--r--pyblackbird_cc/resources/factories.py15
-rw-r--r--pyblackbird_cc/resources/forms.py86
-rw-r--r--pyblackbird_cc/resources/models.py12
-rw-r--r--pyblackbird_cc/resources/s3.py20
-rw-r--r--pyblackbird_cc/resources/services.py6
-rw-r--r--pyblackbird_cc/resources/tests/test_file_processing.py10
-rw-r--r--pyblackbird_cc/resources/tests/test_forms.py1
-rw-r--r--pyblackbird_cc/resources/tests/test_views.py28
-rw-r--r--pyblackbird_cc/resources/urls.py6
-rw-r--r--pyblackbird_cc/resources/views.py19
-rw-r--r--pyblackbird_cc/templates/account/signup.html37
-rw-r--r--pyblackbird_cc/templates/resources/resource_card_standard.html3
15 files changed, 161 insertions, 106 deletions
diff --git a/pyblackbird_cc/payments/tests/test_models.py b/pyblackbird_cc/payments/tests/test_models.py
index 467d6e4..65e7484 100644
--- a/pyblackbird_cc/payments/tests/test_models.py
+++ b/pyblackbird_cc/payments/tests/test_models.py
@@ -29,10 +29,10 @@ def test_subscription_user_unique():
# Create a new user
user_data = {"email": "testuser@example.com", "password": "testpassword123"}
- user = User.objects.create_user(**user_data)
+ user = User.objects.create_user(**user_data) # type: ignore
# Create a subscription for the user
- subscription = Subscription.objects.create(user=user, plan=free_plan)
+ Subscription.objects.create(user=user, plan=free_plan)
# Try to create another subscription for the same user
with pytest.raises(IntegrityError):
@@ -50,13 +50,13 @@ def test_user_signup_assigns_free_subscription(user_data):
"allowed_downloads": 10,
},
) # Create a new user
- user = User.objects.create_user(**user_data)
+ user = User.objects.create_user(**user_data) # type: ignore
# Manually trigger the user_signed_up signal
request = RequestFactory().get("/")
user_signed_up.send(sender=user.__class__, request=request, user=user)
# Check if a SubscriptionPlan was created for the user
- subscription = Subscription.objects.filter(user=user).first()
+ subscription = user.subscription
assert subscription is not None
# Check if the assigned plan is the free plan
diff --git a/pyblackbird_cc/payments/views.py b/pyblackbird_cc/payments/views.py
index 2e53af8..d02a2ab 100644
--- a/pyblackbird_cc/payments/views.py
+++ b/pyblackbird_cc/payments/views.py
@@ -2,12 +2,17 @@ import stripe
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
-from django.shortcuts import render, redirect
+from django.shortcuts import redirect
+from django.shortcuts import render
from django.views import View
from django.views.generic import TemplateView
from pyblackbird_cc.resources.models import Resource
-from .models import ShoppingCart, CartItem, Price, Product
+
+from .models import CartItem
+from .models import Price
+from .models import Product
+from .models import ShoppingCart
stripe.api_key = settings.STRIPE_SECRET_KEY
diff --git a/pyblackbird_cc/resources/admin.py b/pyblackbird_cc/resources/admin.py
index ac45efb..0aa0c68 100644
--- a/pyblackbird_cc/resources/admin.py
+++ b/pyblackbird_cc/resources/admin.py
@@ -1,8 +1,11 @@
# Register your models here.
from django.contrib import admin
-from pyblackbird_cc.resources.models import Resource, ResourceSubcategory, PDFPageSnapshot, PDFResource
+from pyblackbird_cc.resources.models import PDFPageSnapshot
+from pyblackbird_cc.resources.models import PDFResource
+from pyblackbird_cc.resources.models import Resource
from pyblackbird_cc.resources.models import ResourceCategory
+from pyblackbird_cc.resources.models import ResourceSubcategory
from pyblackbird_cc.resources.models import ResourceType
@@ -18,7 +21,7 @@ class ResourceCategoryAdmin(admin.ModelAdmin):
@admin.register(ResourceSubcategory)
class ResourceSubcategoryAdmin(admin.ModelAdmin):
- ordering = ['name']
+ ordering = ["name"]
@admin.register(Resource)
diff --git a/pyblackbird_cc/resources/factories.py b/pyblackbird_cc/resources/factories.py
index 6d6311a..fef8cfb 100644
--- a/pyblackbird_cc/resources/factories.py
+++ b/pyblackbird_cc/resources/factories.py
@@ -34,24 +34,25 @@ class PDFPageSnapshotModelFactory(factory.django.DjangoModelFactory):
pdf_file = factory.SubFactory("pyblackbird_cc.resources.factories.PDFResourceModelFactory")
-
class ResourceModelFactory(factory.django.DjangoModelFactory):
class Meta:
model = Resource
name = factory.Sequence(lambda n: f"Default Resource {n}")
- price = factory.Faker('pydecimal', left_digits=4, right_digits=2, positive=True)
- thumbnail_filenames = factory.List([factory.Faker('file_name', extension='jpg') for _ in range(3)])
+ price = factory.Faker("pydecimal", left_digits=4, right_digits=2, positive=True)
+ thumbnail_filenames = factory.List(
+ [factory.Faker("file_name", extension="jpg") for _ in range(3)]
+ )
resource_type = factory.SubFactory(ResourceTypeModelFactory)
main_resource_category = factory.SubFactory(ResourceCategoryModelFactory)
subcategories = factory.RelatedFactoryList(ResourceCategoryModelFactory, size=2)
- description = factory.Faker('paragraph')
- card_description = factory.Faker('text', max_nb_chars=1000)
+ description = factory.Faker("paragraph")
+ card_description = factory.Faker("text", max_nb_chars=1000)
age_range = factory.Iterator(["5-7", "7-9", "9-11"])
curriculum = factory.Iterator(["English", "Scottish", "No curriculum"])
feature_slot = factory.Iterator(itertools.chain([1, 2, 3], itertools.repeat(None)))
- created_at = factory.Faker('date_time_this_year')
- updated_at = factory.Faker('date_time_this_month')
+ created_at = factory.Faker("date_time_this_year")
+ updated_at = factory.Faker("date_time_this_month")
@factory.post_generation
def pdfs(self, create, extracted, **kwargs):
diff --git a/pyblackbird_cc/resources/forms.py b/pyblackbird_cc/resources/forms.py
index 00869be..2774da5 100644
--- a/pyblackbird_cc/resources/forms.py
+++ b/pyblackbird_cc/resources/forms.py
@@ -1,15 +1,19 @@
import logging
-from typing import List, Tuple
import magic
from crispy_forms.bootstrap import FormActions
from crispy_forms.helper import FormHelper
-from crispy_forms.layout import Submit, Field, Layout, Button
+from crispy_forms.layout import Button
+from crispy_forms.layout import Field
+from crispy_forms.layout import Layout
+from crispy_forms.layout import Submit
from django import forms
-from pyblackbird_cc.resources.models import Resource, ResourceSubcategory
+from pyblackbird_cc.resources.models import Resource
from pyblackbird_cc.resources.models import ResourceCategory
+from pyblackbird_cc.resources.models import ResourceSubcategory
from pyblackbird_cc.resources.models import ResourceType
+
from .models import AGE_RANGE_CHOICES
from .models import CURRICULUM_CHOICES
@@ -19,10 +23,11 @@ ALLOWED_THUMBNAILS = 5
ALLOWED_PDFS = 20
-def _create_choices_tuple() -> List[Tuple[str, str]]:
+def _create_choices_tuple() -> list[tuple[str, str]]:
"""Returns a list of tuples containing resource subcategory names."""
- return sorted(list(ResourceSubcategory.objects.values_list('name', flat=True)), key=str)
-
+ vals = sorted(ResourceSubcategory.objects.values_list("name", flat=True), key=str)
+ out = tuple((x, x) for x in vals)
+ return out
class ResourceCreateForm(forms.Form):
@@ -30,7 +35,8 @@ class ResourceCreateForm(forms.Form):
super().__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.add_input(Submit("submit", "Submit"))
- self.fields['subcategories'].choices = _create_choices_tuple()
+ self.fields["subcategories"].choices = _create_choices_tuple()
+ pass
error_css_class = "error"
required_css_class = "required"
@@ -38,40 +44,42 @@ class ResourceCreateForm(forms.Form):
name = forms.CharField(
max_length=255,
help_text="Concisely describe what the resource is, aiming for"
- " in 35-45 characters. "
- "eg: 'Fractions KS2 Worksheet and Answers.'",
+ " in 35-45 characters. "
+ "eg: 'Fractions KS2 Worksheet and Answers.'",
)
description = forms.CharField(
max_length=5000,
widget=forms.Textarea,
help_text=" You can (and should) use <strong>Markdown</strong> here. "
- "This is your opportunity to clearly explain what your resource "
- "is all "
- "about! It’s worth remembering that you are using the space to "
- "communicate to two "
- "different audiences. Firstly, think about what fellow teachers "
- "would like "
- "to know, such as exactly what the resource contains and how it "
- "could be used in the classroom. Secondly, the words you include "
- "on this page are also talking to internal and external search "
- "engines."
- " External search engines, like Google, show the first 155 characters "
- "of the resource description, so make sure you take advantage "
- "of these "
- "characters by using lots of relevant keywords as part of an "
- "enticing pitch.",
+ "This is your opportunity to clearly explain what your resource "
+ "is all "
+ "about! It’s worth remembering that you are using the space to "
+ "communicate to two "
+ "different audiences. Firstly, think about what fellow teachers "
+ "would like "
+ "to know, such as exactly what the resource contains and how it "
+ "could be used in the classroom. Secondly, the words you include "
+ "on this page are also talking to internal and external search "
+ "engines."
+ " External search engines, like Google, show the first 155 characters "
+ "of the resource description, so make sure you take advantage "
+ "of these "
+ "characters by using lots of relevant keywords as part of an "
+ "enticing pitch.",
)
card_description = forms.CharField(
max_length=1000,
widget=forms.Textarea,
- help_text=("If you enter text here, it will be used in the 'card' description "
- "box on the home page. Max 1000 characters."),
+ help_text=(
+ "If you enter text here, it will be used in the 'card' description "
+ "box on the home page. Max 1000 characters."
+ ),
)
resource_type = forms.ModelChoiceField(queryset=ResourceType.objects.all())
age_range = forms.ChoiceField(
choices=AGE_RANGE_CHOICES,
help_text="Try to be accurate in your choice of age range so that your resource "
- "shows up in the correct searches. (Although we don't have searches yet!)",
+ "shows up in the correct searches. (Although we don't have searches yet!)",
)
curriculum = forms.ChoiceField(
choices=CURRICULUM_CHOICES,
@@ -80,8 +88,8 @@ class ResourceCreateForm(forms.Form):
main_resource_category = forms.ModelChoiceField(
queryset=ResourceCategory.objects.all(),
help_text="Categorise your resource by subject so it shows up in the correct "
- "searches. It's a good idea to limit the number of subjects you select "
- "to one or two to make your resource easier to find.",
+ "searches. It's a good idea to limit the number of subjects you select "
+ "to one or two to make your resource easier to find.",
)
subcategories = forms.MultipleChoiceField(
required=False,
@@ -110,10 +118,10 @@ class ResourceCreateForm(forms.Form):
required=False,
label="Cover images",
help_text="Your cover image will be displayed in the search results and as "
- "the first image on your resource page in the preview function. "
- "It is important to add an eye catching cover image that gives "
- "other teachers an idea about what your resource contains. "
- "You can multi-select up to 5 .png or .jpg files here.",
+ "the first image on your resource page in the preview function. "
+ "It is important to add an eye catching cover image that gives "
+ "other teachers an idea about what your resource contains. "
+ "You can multi-select up to 5 .png or .jpg files here.",
)
pdf_files.widget.attrs.update({"class": "file_upload", "accept": ".pdf"})
thumbnail_files.widget.attrs.update({"class": "file_upload", "accept": ".png,.jpg"})
@@ -121,8 +129,10 @@ class ResourceCreateForm(forms.Form):
min_value=1,
max_value=3,
required=False,
- help_text=("Please enter either 1, 2 or 3 here. This will dictate where on the page "
- "this resource will feature on the main list page."),
+ help_text=(
+ "Please enter either 1, 2 or 3 here. This will dictate where on the page "
+ "this resource will feature on the main list page."
+ ),
)
def clean_thumbnail_files(self):
@@ -159,7 +169,7 @@ class ResourceUpdateMetadataForm(forms.ModelForm):
super().__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.add_input(Submit("submit", "Submit"))
- self.fields['subcategories'].queryset = ResourceSubcategory.objects.all().order_by('name')
+ self.fields["subcategories"].queryset = ResourceSubcategory.objects.all().order_by("name")
error_css_class = "error"
required_css_class = "required"
@@ -191,7 +201,7 @@ class ResourceUpdatePDFsForm(forms.Form):
Field("pdf_files"),
FormActions(
Submit("submit", "Submit", css_class="btn btn-primary"),
- Button("cancel", "Cancel", css_class="btn btn-danger", onclick=f"location.href=''"),
+ Button("cancel", "Cancel", css_class="btn btn-danger", onclick="location.href=''"),
),
)
@@ -245,7 +255,7 @@ class ResourceUpdateThumbnailsForm(forms.Form):
),
required=False,
label="Thumbnail files",
- help_text="You can upload 5 files."
+ help_text="You can upload 5 files.",
)
thumbnail_files.widget.attrs.update({"class": "file_upload", "accept": ".png,.jpg"})
diff --git a/pyblackbird_cc/resources/models.py b/pyblackbird_cc/resources/models.py
index 16186fa..6ecf525 100644
--- a/pyblackbird_cc/resources/models.py
+++ b/pyblackbird_cc/resources/models.py
@@ -68,8 +68,10 @@ class Resource(models.Model):
max_length=1000,
blank=True,
default="",
- help_text=("If you enter text here, it will be used in the 'card' "
- "description box on the home page. Max 1000 characters."),
+ help_text=(
+ "If you enter text here, it will be used in the 'card' "
+ "description box on the home page. Max 1000 characters."
+ ),
)
age_range = models.CharField(
max_length=20,
@@ -90,7 +92,11 @@ class Resource(models.Model):
],
)
feature_slot = models.IntegerField(
- choices=((1, 1), (2, 2), (3, 3)), unique=True, null=True, blank=True, default=0,
+ choices=((1, 1), (2, 2), (3, 3)),
+ unique=True,
+ null=True,
+ blank=True,
+ default=0,
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
diff --git a/pyblackbird_cc/resources/s3.py b/pyblackbird_cc/resources/s3.py
index e9703ca..3693b55 100644
--- a/pyblackbird_cc/resources/s3.py
+++ b/pyblackbird_cc/resources/s3.py
@@ -38,7 +38,7 @@ def get_s3_client() -> Session.client:
endpoint_url=settings.AWS_S3_ENDPOINT_URL,
aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
- region_name=settings.AWS_S3_REGION_NAME
+ region_name=settings.AWS_S3_REGION_NAME,
)
@@ -53,11 +53,7 @@ def upload_files_to_s3(files: Sequence, dir_name: str) -> None:
s3_client = get_s3_client()
for file in files:
logging.info(f"Uploading {file.name} to S3")
- s3_client.upload_fileobj(
- file,
- settings.AWS_STORAGE_BUCKET_NAME,
- f"{dir_name}/{file.name}"
- )
+ s3_client.upload_fileobj(file, settings.AWS_STORAGE_BUCKET_NAME, f"{dir_name}/{file.name}")
def upload_snapshotted_pages_to_s3(snapshotted_pages) -> bool:
@@ -67,9 +63,7 @@ def upload_snapshotted_pages_to_s3(snapshotted_pages) -> bool:
for img in snapshotted_pages[0]:
logging.info(f"Uploading {img} to S3")
s3_client.upload_file(
- img,
- settings.AWS_STORAGE_BUCKET_NAME,
- f"snapshotted_pages/{Path(img).name}"
+ img, settings.AWS_STORAGE_BUCKET_NAME, f"snapshotted_pages/{Path(img).name}"
)
return True
if collection_type in ["MULTI_PDF_SINGLE_PAGE", "MULTI_PDF_MULTI_PAGE"]:
@@ -77,9 +71,7 @@ def upload_snapshotted_pages_to_s3(snapshotted_pages) -> bool:
for img in pdf:
logging.info(f"Uploading {img} to S3")
s3_client.upload_file(
- img,
- settings.AWS_STORAGE_BUCKET_NAME,
- f"snapshotted_pages/{Path(img).name}"
+ img, settings.AWS_STORAGE_BUCKET_NAME, f"snapshotted_pages/{Path(img).name}"
)
return True
return False
@@ -94,8 +86,8 @@ def upload_to_s3(pdf_files, thumbnail_files, snapshotted_pages) -> bool:
:return: True if the files was uploaded, False otherwise
"""
try:
- upload_files_to_s3(pdf_files, dir_name='pdfuploads')
- upload_files_to_s3(thumbnail_files, dir_name='thumbnails')
+ upload_files_to_s3(pdf_files, dir_name="pdfuploads")
+ upload_files_to_s3(thumbnail_files, dir_name="thumbnails")
return upload_snapshotted_pages_to_s3(snapshotted_pages)
except ClientError:
logging.exception("Error uploading files to S3")
diff --git a/pyblackbird_cc/resources/services.py b/pyblackbird_cc/resources/services.py
index 441f623..03c53af 100644
--- a/pyblackbird_cc/resources/services.py
+++ b/pyblackbird_cc/resources/services.py
@@ -19,14 +19,12 @@ def get_pdf_metadata_from_path(file_path: str) -> PDFMetadata:
:param file_path:
:return: PDFMetadata
"""
- if file_path is None:
- raise ValueError("file_path cannot be None")
if not os.path.isfile(file_path):
raise ValueError("file_path must be a file. {file_path} is not a file.")
reader = PdfReader(file_path)
n_pages = len(reader.pages)
file_size = os.path.getsize(file_path)
- #pdf.close()
+ # pdf.close()
return PDFMetadata(file_name=file_path, file_size=file_size, n_pages=n_pages)
@@ -36,8 +34,6 @@ def export_pages_as_images(file_path: str) -> list[str]:
:param file_path:
:return: List of paths to the JPEG images
"""
- if file_path is None:
- raise ValueError("file_path cannot be None")
output_dir = tempfile.mkdtemp() # Create a temporary directory
reader = PdfReader(file_path)
n_pages = len(reader.pages)
diff --git a/pyblackbird_cc/resources/tests/test_file_processing.py b/pyblackbird_cc/resources/tests/test_file_processing.py
index e4ac781..7b95a9d 100644
--- a/pyblackbird_cc/resources/tests/test_file_processing.py
+++ b/pyblackbird_cc/resources/tests/test_file_processing.py
@@ -1,3 +1,6 @@
+from pathlib import Path
+
+from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.core.files.uploadedfile import SimpleUploadedFile
@@ -5,9 +8,8 @@ from django.core.files.uploadedfile import TemporaryUploadedFile
from django.test import TestCase
from django.urls import reverse
-from ..utils import _get_pdf_collection_type
-
from .. import services
+from ..utils import _get_pdf_collection_type
def test_detect_snapshotted_pdf_collection():
@@ -25,7 +27,9 @@ def test_detect_snapshotted_pdf_collection():
class PDFFileUploadTestCase(TestCase):
def setUp(self):
self.url = reverse("resources:create_resource")
- self.test_file_path = "resources/tests/testdata/test_small_file.pdf"
+ self.test_file_path = Path(
+ settings.BASE_DIR / "pyblackbird_cc" / "resources/tests/testdata/test_small_file.pdf"
+ )
# Create a test user
self.email = "testuser@example.com"
diff --git a/pyblackbird_cc/resources/tests/test_forms.py b/pyblackbird_cc/resources/tests/test_forms.py
index 9190f55..318071d 100644
--- a/pyblackbird_cc/resources/tests/test_forms.py
+++ b/pyblackbird_cc/resources/tests/test_forms.py
@@ -1,5 +1,4 @@
import pytest
-from django.core.exceptions import ValidationError
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db import IntegrityError
from django.test import TestCase
diff --git a/pyblackbird_cc/resources/tests/test_views.py b/pyblackbird_cc/resources/tests/test_views.py
index e5025a5..87b9fc0 100644
--- a/pyblackbird_cc/resources/tests/test_views.py
+++ b/pyblackbird_cc/resources/tests/test_views.py
@@ -1,6 +1,8 @@
import unittest
+from pathlib import Path
import pytest
+from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.models import User
from django.core.files.uploadedfile import SimpleUploadedFile
@@ -8,11 +10,11 @@ from django.test import RequestFactory
from django.test import TestCase
from django.urls import reverse
-from .. import services
-from ..forms import ResourceCreateForm
-from ..models import ResourceCategory
-from ..models import ResourceType
-from ..views import create_resource
+from pyblackbird_cc.resources import services
+from pyblackbird_cc.resources.forms import ResourceCreateForm
+from pyblackbird_cc.resources.models import ResourceCategory
+from pyblackbird_cc.resources.models import ResourceType
+from pyblackbird_cc.resources.views import create_resource
pytestmark = pytest.mark.django_db
@@ -32,21 +34,25 @@ def test_create_resource_view(client):
@pytest.mark.django_db
def test_create_resource_has_form(client):
User = get_user_model()
- user = User.objects.create_user(email='testuser@example.com', password='12345')
- client.login(email='testuser@example.com', password='12345')
+ user = User.objects.create_user(email="testuser@example.com", password="12345")
+ client.login(email="testuser@example.com", password="12345")
url = reverse("resources:create_resource")
response = client.get(url)
assert response.status_code == 200
- assert 'form' in response.context
- assert isinstance(response.context['form'], ResourceCreateForm)
+ assert "form" in response.context
+ assert isinstance(response.context["form"], ResourceCreateForm)
class PDFFileUploadTestCase(TestCase):
def setUp(self):
self.url = reverse("resources:create_resource")
- self.two_page_pdf = "resources/tests/testdata/two_page.pdf"
- self.seven_page_pdf = "resources/tests/testdata/seven_page.pdf"
+ self.two_page_pdf = Path(
+ settings.BASE_DIR / "pyblackbird_cc" / "resources/tests/testdata/two_page.pdf"
+ )
+ self.seven_page_pdf = Path(
+ settings.BASE_DIR / "pyblackbird_cc" / "resources/tests/testdata/seven_page.pdf"
+ )
# Create a test user
self.email = "testuser@example.com"
diff --git a/pyblackbird_cc/resources/urls.py b/pyblackbird_cc/resources/urls.py
index 34ea0c8..87cd3b0 100644
--- a/pyblackbird_cc/resources/urls.py
+++ b/pyblackbird_cc/resources/urls.py
@@ -13,7 +13,11 @@ urlpatterns = [
views.update_resource_metadata,
name="resource_update_metadata",
),
- path("resource/update-thumbnails/<int:pk>", views.update_resource_thumbnails, name="resource_update_thumbnails"),
+ path(
+ "resource/update-thumbnails/<int:pk>",
+ views.update_resource_thumbnails,
+ name="resource_update_thumbnails",
+ ),
path("resource/add-pdfs/<int:pk>", views.add_resource_pdfs, name="resource_update_pdfs"),
]
diff --git a/pyblackbird_cc/resources/views.py b/pyblackbird_cc/resources/views.py
index f802350..ca7ce73 100644
--- a/pyblackbird_cc/resources/views.py
+++ b/pyblackbird_cc/resources/views.py
@@ -3,6 +3,7 @@ import os
import tempfile
from collections.abc import Generator
from dataclasses import dataclass
+from typing import Optional
from django.conf import settings
from django.contrib import messages
@@ -45,10 +46,10 @@ class ResourceInfo:
subcategories: str | None
age_range: str | None
pdf_filenames: list[str]
- pdf_urls: list[str]
+ pdf_urls: list[Optional[str]]
snapshot_urls: dict[str, list[str]]
thumbnail_filenames: list[str]
- thumbnail_urls: list[str]
+ thumbnail_urls: list[Optional[str]]
feature_slot: int
created: str
updated: str
@@ -114,8 +115,8 @@ def _extract_metadata_from_resource(resource_obj) -> ResourceInfo | None:
created=resource_obj.created_at,
updated=resource_obj.updated_at,
)
- except Exception as e:
- logging.exception(f"Error extracting resource information: {e}")
+ except Exception:
+ logging.exception("Error extracting resource information: ")
return None
@@ -147,16 +148,6 @@ def index(request):
return render(request, "resources/resource_list.html", context)
-def _write_pdf_to_tempdir(f) -> str:
- temp_dir = tempfile.mkdtemp()
- file_path = os.path.join(temp_dir, f.name)
-
- with open(file_path, "wb") as destination:
- for chunk in f.chunks():
- destination.write(chunk)
- return file_path
-
-
def create_metadata(pdf_files) -> Generator[tuple[services.PDFMetadata, str], None, None]:
"""
Generates PDF metadata and snapshot images for a list of PDF files.
diff --git a/pyblackbird_cc/templates/account/signup.html b/pyblackbird_cc/templates/account/signup.html
new file mode 100644
index 0000000..9dd81fd
--- /dev/null
+++ b/pyblackbird_cc/templates/account/signup.html
@@ -0,0 +1,37 @@
+ {% extends "account/base_entrance.html" %}
+ {% load allauth i18n %}
+ {% block head_title %}
+ {% trans "Signup" %}
+ {% endblock head_title %}
+ {% block content %}
+ {% element h1 %}
+ {% trans "Sign Up" %}
+ <p>There are lots of benefits to signing up!</p>
+ {% endelement %}
+ {% setvar link %}
+ <a href="{{ login_url }}">
+ {% endsetvar %}
+ {% setvar end_link %}
+ </a>
+ {% endsetvar %}
+ <p>{% blocktranslate %}Already have an account? Then please {{ link }}sign in{{ end_link }}.{% endblocktranslate %}</p>
+ {% if not SOCIALACCOUNT_ONLY %}
+ {% url 'account_signup' as action_url %}
+ {% element form form=form method="post" action=action_url tags="entrance,signup" %}
+ {% slot body %}
+ {% csrf_token %}
+ {% element fields form=form unlabeled=True %}
+ {% endelement %}
+ {{ redirect_field }}
+ {% endslot %}
+ {% slot actions %}
+ {% element button tags="prominent,signup" type="submit" %}
+ {% trans "Sign Up" %}
+ {% endelement %}
+ {% endslot %}
+ {% endelement %}
+ {% endif %}
+ {% if SOCIALACCOUNT_ENABLED %}
+ {% include "socialaccount/snippets/login.html" with page_layout="entrance" %}
+ {% endif %}
+ {% endblock content %}
diff --git a/pyblackbird_cc/templates/resources/resource_card_standard.html b/pyblackbird_cc/templates/resources/resource_card_standard.html
index 68ea0dc..9d560eb 100644
--- a/pyblackbird_cc/templates/resources/resource_card_standard.html
+++ b/pyblackbird_cc/templates/resources/resource_card_standard.html
@@ -32,6 +32,7 @@
<span class="badge bg-info me-2">Feature slot: {{ resource.feature_slot }}</span>
{% endif %}
</div>
+ <p>{{ resource.card_description }}</p>
<p class="card-text m-1"><small class="text-muted">1 credit</small></p>
</div>
</div>
@@ -47,4 +48,4 @@
{% endif %}
</div>
-</div> \ No newline at end of file
+</div>