Skip to content

Feat(videoReq) have the ability for someone to request an educational video #582

Merged
A1L13N merged 22 commits into
alphaonelabs:mainfrom
varruunnn:VideoReq
Apr 30, 2025
Merged

Feat(videoReq) have the ability for someone to request an educational video #582
A1L13N merged 22 commits into
alphaonelabs:mainfrom
varruunnn:VideoReq

Conversation

@varruunnn
Copy link
Copy Markdown
Contributor

@varruunnn varruunnn commented Apr 23, 2025

Fixes #254

Video / SS

Recording.1.1.mp4

Checklist

  • Did you run the pre-commit? (If not, your PR will most likely not pass — please ensure it passes pre-commit)
  • Did you test the change? (Ensure you didn’t just prompt the AI and blindly commit — test the code and confirm it works)
  • Added screenshots to the PR description (if applicable)

Summary by CodeRabbit

  • New Features

    • Introduced a "Video Requests" section, allowing users to request educational videos on specific topics.
    • Added a dedicated page to view and filter video requests by category, with details such as requester, status, and fulfillment.
    • Enabled authenticated users to submit new video requests through a user-friendly form.
    • Added a "Video Requests" link to the COMMUNITY menu for easy navigation.
    • Displayed recent video requests alongside educational videos on the main listing page.
    • Included a sidebar form on the videos list page for quick video request submissions.
  • Bug Fixes

    • Improved survey URL pattern consistency.
  • Chores

    • Added input sanitization for video request submissions to enhance security.
    • Updated dependencies to include HTML sanitization support.

have the ability for someone to request an educational video - example I'd like a video on how to take an issue from github, code the solution and submit a PR
>> have the ability for someone to request an educational video - example I'd like a video on how to take an issue from github, code the solution and submit a PR
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2025

"""

Walkthrough

This change introduces a complete feature for users to request educational videos. It adds a new VideoRequest model, corresponding database migration, admin registration, and a Django ModelForm with input sanitization. New views and URL patterns allow authenticated users to submit and view video requests, with templates for both listing and submitting requests. The navigation menu is updated to include a link to the video request page. The bleach library is added as a dependency to sanitize user input in forms.

Changes

File(s) Change Summary
web/models.py, web/migrations/0061_...videorequest.py Added VideoRequest model to represent user requests for educational videos, with fields for title, description, category, requester, status, and fulfillment; migration created for the model and altered EducationalVideo.description to be optional.
web/forms.py Added VideoRequestForm ModelForm with custom widgets, input sanitization using bleach, and alphabetically ordered category choices.
web/views.py Added video_request_list and submit_video_request views to display and handle submission of video requests, both requiring user authentication. Enhanced educational_videos_list view to include recent video requests.
web/urls.py Added URL patterns for listing and submitting video requests; updated survey submission pattern to use <int:pk>.
web/admin.py Registered VideoRequest in the Django admin with a custom admin class for list display, filtering, and search.
web/templates/videos/request_list.html, web/templates/videos/submit_request.html Added templates for listing video requests (with filtering, status badges, and fulfillment links) and for submitting new requests (with form fields and error display).
web/templates/base.html Added "Video Requests" navigation link to the COMMUNITY dropdown in both desktop and mobile views.
web/templates/videos/list.html Enhanced video listing page with a sidebar form for submitting video requests and a section showing recent video requests with pagination and links.
requirements.txt Added bleach==6.2.0 as a dependency for input sanitization.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Browser
    participant DjangoViews
    participant Database

    User->>Browser: Navigates to "Video Requests"
    Browser->>DjangoViews: GET /videos/requests/
    DjangoViews->>Database: Query VideoRequest (optionally filtered by category)
    Database-->>DjangoViews: VideoRequest list
    DjangoViews-->>Browser: Render request_list.html

    User->>Browser: Clicks "Submit Request"
    Browser->>DjangoViews: GET /videos/requests/submit/
    DjangoViews-->>Browser: Render submit_request.html (form)

    User->>Browser: Fills and submits form
    Browser->>DjangoViews: POST /videos/requests/submit/ (form data)
    DjangoViews->>Database: Validate, sanitize, save VideoRequest
    Database-->>DjangoViews: Saved
    DjangoViews-->>Browser: Redirect to /videos/requests/ with success message
Loading

Assessment against linked issues

Objective Addressed Explanation
Allow users to request an educational video (fields, submission, listing, admin, navigation) (#254)

Suggested reviewers

  • A1L13N
    """

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a31f858 and 313f5bc.

⛔ Files ignored due to path filters (1)
  • poetry.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • pyproject.toml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-and-test
  • GitHub Check: Run Tests
🔇 Additional comments (1)
pyproject.toml (1)

36-36:

Details

✅ Verification successful

Ensure consistency of the new bleach dependency across all manifests
The addition of bleach = "^6.2.0" in your Poetry dependencies looks correct for sanitizing user input in VideoRequestForm. Please verify that any other dependency files (e.g., requirements.txt) have also been updated to include the same version to keep your production and CI environments in sync.

Run this script to confirm presence in requirements.txt:


🏁 Script executed:

#!/usr/bin/env bash
# Verify that bleach is listed in requirements.txt
if rg -q "^bleach" requirements.txt; then
  echo "✔️ bleach found in requirements.txt"
else
  echo "❌ ERROR: bleach not found in requirements.txt" >&2
  exit 1
fi

Length of output: 115


Dependency Alignment Verified
The bleach = "^6.2.0" entry is present in both pyproject.toml and requirements.txt. No further updates are needed.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @varruunnn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

Summary of Changes

This pull request introduces the functionality for users to request educational videos. It includes a new VideoRequest model, a form for submitting requests, views for listing and submitting requests, and updates to the admin interface and base template to include the new feature. The changes also include a migration to create the VideoRequest model in the database.

Highlights

  • Model Creation: A new VideoRequest model is created with fields for title, description, category, requester, creation timestamp, status, and a foreign key to the EducationalVideo model for when the request is fulfilled.
  • Form Creation: A VideoRequestForm is created to allow users to submit video requests, including fields for title, description, and category.
  • Views Implementation: Two new views are implemented: video_request_list for displaying a list of video requests, and submit_video_request for handling the submission of new video requests.
  • Admin Interface Integration: The VideoRequest model is registered in the admin interface, allowing administrators to manage video requests.
  • Template Updates: The base template is updated to include a link to the video request list page.

Changelog

Click here to see the changelog
  • web/admin.py
    • Added VideoRequest to the list of registered models.
    • Registered VideoRequestAdmin to customize the admin interface for video requests, including list display, filters, and search fields.
  • web/forms.py
    • Imported the VideoRequest model.
    • Added VideoRequestForm to the list of forms.
    • Created the VideoRequestForm with fields for title, description, and category, including Tailwind CSS styling for the widgets. The category field is ordered by name.
  • web/migrations/0060_alter_educationalvideo_description_videorequest.py
    • Created a migration to add the VideoRequest model to the database, including fields for title, description, category, requester, creation timestamp, status, and fulfilled_by.
    • Modified the EducationalVideo model to include a help text for the description field.
  • web/models.py
    • Added the VideoRequest model with fields for title, description, category, requester, creation timestamp, status, and fulfilled_by, including verbose names and ordering.
  • web/templates/base.html
    • Added a link to the video request list page in the base template's navigation.
  • web/templates/videos/request_list.html
    • Created a new template for displaying a list of video requests, including filtering by category and displaying request details.
  • web/templates/videos/submit_request.html
    • Created a new template for submitting a video request, including the VideoRequestForm and instructions for users.
  • web/urls.py
    • Added URLs for the video request list and submit video request views.
  • web/views.py
    • Imported the VideoRequestForm.
    • Imported the VideoRequest model.
    • Implemented the video_request_list view to display a list of video requests with optional category filtering.
    • Implemented the submit_video_request view to handle the submission of new video requests.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


A video's request,
A learning journey starts now,
Knowledge will unfold.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new feature for requesting educational videos. Overall, the code is well-structured and implements the desired functionality. However, there are some areas that could be improved, particularly around input validation, template rendering, and security.

Summary of Findings

  • Missing input validation: The code lacks input validation for the 'title' and 'description' fields in the VideoRequest model and VideoRequestForm. This could lead to issues with data integrity and potential security vulnerabilities.
  • Category counts in video request list: The category counts in the video request list template are referencing category_counts.category_counts.category.slug which seems unnecessarily nested and likely incorrect. This will prevent the category counts from displaying correctly.
  • Lack of permissions check: There is no permission check in the video_request_list view to ensure that only authenticated users can view the video requests. This could expose the video requests to unauthorized users.

Merge Readiness

The pull request is not yet ready for merging. The high severity issues regarding missing input validation and lack of permissions check should be addressed before merging. The medium severity issue regarding the category counts in the video request list should also be addressed to ensure the feature functions as expected. Please have others review and approve this code before merging.

Comment thread web/models.py
Comment thread web/models.py
Comment thread web/views.py
Comment thread web/templates/videos/request_list.html Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🔭 Outside diff range comments (1)
web/models.py (1)

2928-2957: 🧹 Nitpick (assertive)

Well-structured VideoRequest model with appropriate relationships

The VideoRequest model is well-designed with appropriate field types, relationships, and Meta configuration. The model effectively captures all required data for the video request feature.

Consider these minor improvements:

  1. Define status choices as class constants for better maintainability:
class VideoRequest(models.Model):
    """Model for users to request educational videos on specific topics."""

+   STATUS_PENDING = 'pending'
+   STATUS_APPROVED = 'approved'
+   STATUS_FULFILLED = 'fulfilled'
+   STATUS_REJECTED = 'rejected'
+   
+   STATUS_CHOICES = [
+       (STATUS_PENDING, "Pending"),
+       (STATUS_APPROVED, "Approved"),
+       (STATUS_FULFILLED, "Fulfilled"),
+       (STATUS_REJECTED, "Rejected"),
+   ]

    # fields remain the same
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
-       default="pending",
+       default=STATUS_PENDING,
        )
  1. Add return type annotation to the str method:
-   def __str__(self):
+   def __str__(self) -> str:
        return self.title
  1. Add ClassVar annotations as suggested by the static analyzer:
    class Meta:
-       verbose_name = "Video Request"
-       verbose_name_plural = "Video Requests"
-       ordering = ["-created_at"]
+       verbose_name: typing.ClassVar[str] = "Video Request"
+       verbose_name_plural: typing.ClassVar[str] = "Video Requests"
+       ordering: typing.ClassVar[list[str]] = ["-created_at"]
🧰 Tools
🪛 Ruff (0.8.2)

2947-2947: Trailing comma missing

Add trailing comma

(COM812)


2953-2953: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


2955-2955: Missing return type annotation for special method __str__

Add return type annotation: str

(ANN204)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ba2523 and 8dba43e.

📒 Files selected for processing (9)
  • web/admin.py (2 hunks)
  • web/forms.py (3 hunks)
  • web/migrations/0060_alter_educationalvideo_description_videorequest.py (1 hunks)
  • web/models.py (1 hunks)
  • web/templates/base.html (2 hunks)
  • web/templates/videos/request_list.html (1 hunks)
  • web/templates/videos/submit_request.html (1 hunks)
  • web/urls.py (1 hunks)
  • web/views.py (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
web/admin.py (1)
web/models.py (1)
  • VideoRequest (2928-2956)
web/urls.py (1)
web/views.py (2)
  • video_request_list (7606-7638)
  • submit_video_request (7642-7656)
web/views.py (2)
web/forms.py (6)
  • VideoRequestForm (1876-1906)
  • save (249-287)
  • save (615-640)
  • save (725-742)
  • save (1493-1506)
  • save (1685-1700)
web/models.py (13)
  • VideoRequest (2928-2956)
  • Subject (197-215)
  • save (100-104)
  • save (158-194)
  • save (212-215)
  • save (279-313)
  • save (404-436)
  • save (556-558)
  • save (790-793)
  • save (923-928)
  • save (1045-1050)
  • save (1103-1108)
  • save (1183-1186)
🪛 Ruff (0.8.2)
web/views.py

7606-7606: Missing return type annotation for public function video_request_list

(ANN201)


7606-7606: Missing type annotation for function argument request

(ANN001)


7626-7626: Trailing comma missing

Add trailing comma

(COM812)


7642-7642: Missing return type annotation for public function submit_video_request

(ANN201)


7642-7642: Missing type annotation for function argument request

(ANN001)

web/migrations/0060_alter_educationalvideo_description_videorequest.py

10-13: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


15-75: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


47-47: Trailing comma missing

Add trailing comma

(COM812)

web/forms.py

1881-1881: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1882-1901: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1891-1891: Trailing comma missing

Add trailing comma

(COM812)


1898-1898: Trailing comma missing

Add trailing comma

(COM812)


1899-1899: Trailing comma missing

Add trailing comma

(COM812)


1903-1903: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


1903-1903: Missing type annotation for *args

(ANN002)


1903-1903: Missing type annotation for **kwargs

(ANN003)

web/models.py

2947-2947: Trailing comma missing

Add trailing comma

(COM812)


2953-2953: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


2955-2955: Missing return type annotation for special method __str__

Add return type annotation: str

(ANN204)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Run Tests
  • GitHub Check: build-and-test
🔇 Additional comments (17)
web/templates/base.html (2)

271-274: Excellent implementation of the new navigation link!

The new "Video Requests" link is appropriately placed in the COMMUNITY dropdown menu, consistent with the site's navigation structure and styled to match other links in this section.


650-654: Good mobile navigation consistency.

The same video requests navigation option is properly implemented in the mobile menu, maintaining UI consistency across different viewport sizes.

web/urls.py (1)

121-123: Well-structured URL patterns with proper authentication.

The URL patterns are logically organized and follow the project's convention. Good use of the login_required decorator to ensure only authenticated users can submit video requests.

web/templates/videos/submit_request.html (1)

1-59: Well-designed and accessible form template.

This form template is well-structured with proper field labeling, error handling, and helpful user guidance. The template follows the application's design patterns using Tailwind CSS and maintains consistency with the rest of the UI.

web/admin.py (2)

55-55: Model import added correctly.

The VideoRequest model is properly imported with the rest of the models.


887-892: Well-configured admin registration for the new model.

The VideoRequestAdmin class provides a good configuration for managing video requests in the admin interface, with appropriate list display columns, filters, and search fields.

web/views.py (2)

103-103: Import addition looks good.

The VideoRequestForm import has been correctly added to the imports from .forms.


167-167: Import addition looks good.

The VideoRequest model has been correctly added to the imports from .models.

web/templates/videos/request_list.html (4)

62-64: Status badge implementation is well done

The color-coded status badges provide clear visual feedback about the request status. The conditional class assignment based on status is implemented effectively.


71-76: Good implementation of conditional link to fulfilling video

The conditional check for fulfilled_by and the link to the educational video is properly implemented.


82-89: Empty state is well handled

The empty state provides a clear call-to-action for users when no video requests exist, encouraging engagement.


7-8: Responsive layout implementation

Good use of Tailwind's responsive utilities with flex-col md:flex-row to create a layout that switches from column to row on medium screens and larger.

web/forms.py (3)

1876-1907: Well-structured model form for video requests

The VideoRequestForm implementation follows Django best practices with appropriate field selections and custom Tailwind CSS widgets. Good job overriding the init method to provide an alphabetically sorted category dropdown.

🧰 Tools
🪛 Ruff (0.8.2)

1881-1881: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1882-1901: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1891-1891: Trailing comma missing

Add trailing comma

(COM812)


1898-1898: Trailing comma missing

Add trailing comma

(COM812)


1899-1899: Trailing comma missing

Add trailing comma

(COM812)


1903-1903: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


1903-1903: Missing type annotation for *args

(ANN002)


1903-1903: Missing type annotation for **kwargs

(ANN003)


89-89: Appropriate export in all list

The form has been properly added to the module's all list for export.


52-52: Model imported correctly

VideoRequest is correctly imported from the models module.

web/models.py (1)

2946-2949: Good relationship to EducationalVideo

The optional fulfilled_by relationship to EducationalVideo with SET_NULL on_delete behavior is a good choice. This allows administrators to mark requests as fulfilled by linking to existing videos, while ensuring data integrity if videos are deleted.

🧰 Tools
🪛 Ruff (0.8.2)

2947-2947: Trailing comma missing

Add trailing comma

(COM812)

web/migrations/0060_alter_educationalvideo_description_videorequest.py (1)

15-74: Properly structured migration for VideoRequest model

This auto-generated migration correctly implements the necessary database changes:

  1. Alters the EducationalVideo.description field to make it optional with helpful text
  2. Creates the new VideoRequest model with all required fields and relationships

The migration looks clean and should apply without issues.

🧰 Tools
🪛 Ruff (0.8.2)

15-75: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


47-47: Trailing comma missing

Add trailing comma

(COM812)

Comment thread web/views.py
Comment thread web/views.py
Comment thread web/templates/videos/request_list.html Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 23, 2025
@varruunnn
Copy link
Copy Markdown
Contributor Author

@A1L13N please check slack dm

@A1L13N
Copy link
Copy Markdown
Contributor

A1L13N commented Apr 23, 2025

@A1L13N please check slack dm

I did, yes, let’s try bleach

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (2)
web/views.py (2)

7606-7639: Add type hints to improve maintainability.

-@login_required
-def video_request_list(request):
+@login_required
+def video_request_list(request: HttpRequest) -> HttpResponse:

Add a trailing comma after the last item in the dictionary for consistent style:

    category_counts = dict(
        VideoRequest.objects.values("category__name", "category__slug")
        .annotate(count=Count("id"))
-        .values_list("category__slug", "count")
+        .values_list("category__slug", "count"),
    )
🧰 Tools
🪛 Ruff (0.8.2)

7607-7607: Missing return type annotation for public function video_request_list

(ANN201)


7607-7607: Missing type annotation for function argument request

(ANN001)


7627-7627: Trailing comma missing

Add trailing comma

(COM812)


7642-7657: Add type hints to improve maintainability.

The function is well implemented with proper authentication, form validation, user association, and feedback messages, but would benefit from type hints:

-@login_required
-def submit_video_request(request):
+@login_required
+def submit_video_request(request: HttpRequest) -> HttpResponse:
🧰 Tools
🪛 Ruff (0.8.2)

7643-7643: Missing return type annotation for public function submit_video_request

(ANN201)


7643-7643: Missing type annotation for function argument request

(ANN001)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8dba43e and 64bff40.

📒 Files selected for processing (3)
  • requirements.txt (1 hunks)
  • web/forms.py (4 hunks)
  • web/views.py (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
web/forms.py (2)
web/models.py (18)
  • VideoRequest (2928-2956)
  • Meta (45-46)
  • Meta (206-207)
  • Meta (398-399)
  • Meta (544-545)
  • Meta (600-601)
  • Meta (622-623)
  • Meta (676-679)
  • Meta (730-731)
  • Meta (783-785)
  • Meta (834-835)
  • Meta (874-876)
  • Meta (898-899)
  • Meta (917-918)
  • Meta (972-973)
  • Meta (1039-1040)
  • Meta (1070-1071)
  • Subject (197-215)
web/widgets.py (3)
  • TailwindInput (5-16)
  • TailwindTextarea (19-31)
  • TailwindSelect (62-73)
🪛 Ruff (0.8.2)
web/forms.py

1888-1888: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1889-1908: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1898-1898: Trailing comma missing

Add trailing comma

(COM812)


1905-1905: Trailing comma missing

Add trailing comma

(COM812)


1906-1906: Trailing comma missing

Add trailing comma

(COM812)


1910-1910: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


1910-1910: Missing type annotation for *args

(ANN002)


1910-1910: Missing type annotation for **kwargs

(ANN003)


1915-1915: Missing return type annotation for public function clean_title

(ANN201)


1920-1920: Missing return type annotation for public function clean_description

(ANN201)


1929-1929: Unnecessary assignment to cleaned before return statement

Remove unnecessary assignment

(RET504)

web/views.py

7607-7607: Missing return type annotation for public function video_request_list

(ANN201)


7607-7607: Missing type annotation for function argument request

(ANN001)


7627-7627: Trailing comma missing

Add trailing comma

(COM812)


7643-7643: Missing return type annotation for public function submit_video_request

(ANN201)


7643-7643: Missing type annotation for function argument request

(ANN001)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Run Tests
  • GitHub Check: build-and-test
🔇 Additional comments (8)
web/forms.py (8)

4-4: Import for XSS protection added.

The bleach library is imported to provide XSS protection in the new VideoRequestForm class. This is a good security practice to sanitize user input before storing it in the database.


53-53: Added VideoRequest to model imports.

The VideoRequest model is now imported from models, allowing it to be used in the new form class.


90-90: Added VideoRequestForm to all exports.

The new form class has been properly added to the __all__ list, making it available for import from other modules.


1877-1880: Well-defined security constants for HTML sanitization.

The constants ALLOWED_TAGS and ALLOWED_ATTRIBUTES define a limited set of safe HTML elements and attributes for user input sanitization. This follows security best practices by explicitly defining what's allowed rather than trying to block what's not allowed.


1883-1909: Comprehensive form setup with appropriate widgets and placeholders.

The form is well structured with proper field definitions, helpful placeholders, and Tailwind styling. The docstring clearly indicates the form's purpose and its security features.

🧰 Tools
🪛 Ruff (0.8.2)

1888-1888: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1889-1908: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1898-1898: Trailing comma missing

Add trailing comma

(COM812)


1905-1905: Trailing comma missing

Add trailing comma

(COM812)


1906-1906: Trailing comma missing

Add trailing comma

(COM812)


1910-1914: Category field ordering improvement.

The __init__ method properly overrides the queryset for the category field to order subjects alphabetically by name, improving usability.

🧰 Tools
🪛 Ruff (0.8.2)

1910-1910: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


1910-1910: Missing type annotation for *args

(ANN002)


1910-1910: Missing type annotation for **kwargs

(ANN003)


1915-1919: Secure XSS protection for title field.

The clean_title method uses bleach.clean to strip all HTML tags from the title field, ensuring that only plain text is stored. This is appropriate for title fields which shouldn't contain formatting.

🧰 Tools
🪛 Ruff (0.8.2)

1915-1915: Missing return type annotation for public function clean_title

(ANN201)


1920-1929: Secure description processing with limited HTML capabilities.

The clean_description method allows a limited set of HTML tags and attributes, providing users with basic formatting options while preventing XSS attacks. This is a good balance between usability and security.

🧰 Tools
🪛 Ruff (0.8.2)

1920-1920: Missing return type annotation for public function clean_description

(ANN201)


1929-1929: Unnecessary assignment to cleaned before return statement

Remove unnecessary assignment

(RET504)

Comment thread requirements.txt Outdated
Comment thread web/forms.py Outdated
Comment thread web/forms.py Outdated
Comment thread web/forms.py Outdated
Comment thread web/forms.py
coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 23, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
web/forms.py (1)

1886-1908: 🧹 Nitpick (assertive)

Add missing trailing commas for better maintainability.

Several lines are missing trailing commas, which makes future modifications more error-prone.

        widgets = {
            "title": TailwindInput(attrs={"placeholder": "Title of the video you're requesting"}),
            "description": TailwindTextarea(
                attrs={
                    "rows": 4,
                    "placeholder": (
                        "Describe what you'd like to learn from this video "
-                        "(e.g., 'I'd like a video on calculus basics')",
+                        "(e.g., 'I'd like a video on calculus basics')",
                    ),
                }
            ),
            "category": TailwindSelect(
                attrs={
                    "class": (
                        "w-full px-4 py-2 border border-gray-300 dark:border-gray-600"
-                        " rounded-lg focus:ring-2 focus:ring-blue-500",
+                        " rounded-lg focus:ring-2 focus:ring-blue-500",
                    )
                }
            ),
        }
🧰 Tools
🪛 Ruff (0.8.2)

1888-1888: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1889-1908: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1898-1898: Trailing comma missing

Add trailing comma

(COM812)


1905-1905: Trailing comma missing

Add trailing comma

(COM812)


1906-1906: Trailing comma missing

Add trailing comma

(COM812)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64bff40 and cde6260.

📒 Files selected for processing (2)
  • requirements.txt (1 hunks)
  • web/forms.py (4 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
web/forms.py

2-2: typing.Dict is deprecated, use dict instead

(UP035)


2-2: typing.List is deprecated, use list instead

(UP035)


1881-1881: Use list instead of List for type annotation

Replace with list

(UP006)


1882-1882: Use dict instead of Dict for type annotation

Replace with dict

(UP006)


1882-1882: Use list instead of List for type annotation

Replace with list

(UP006)


1888-1888: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1889-1908: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1898-1898: Trailing comma missing

Add trailing comma

(COM812)


1905-1905: Trailing comma missing

Add trailing comma

(COM812)


1906-1906: Trailing comma missing

Add trailing comma

(COM812)


1910-1910: Missing type annotation for *args

(ANN002)


1910-1910: Missing type annotation for **kwargs

(ANN003)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-and-test
  • GitHub Check: Run Tests
🔇 Additional comments (6)
requirements.txt (1)

69-69: Good addition of the bleach dependency with proper version constraints.

The bleach library is correctly added with the same Python version constraints as other dependencies, maintaining consistency in the requirements file. This dependency supports the XSS protection in the new VideoRequestForm.

web/forms.py (5)

54-54: LGTM - Model is correctly imported.

The VideoRequest model import has been properly added to support the new form.


91-91: LGTM - Form correctly exported.

VideoRequestForm is properly added to the __all__ list, making it available for import from this module.


1878-1880: Good implementation of a form for video requests with security in mind.

The form class is well-documented and its purpose is clearly stated, highlighting the security aspect (XSS protection).


1914-1917: LGTM - Good sanitation of the title field.

The title field is properly sanitized by removing all HTML tags, which is appropriate for this type of data.


1918-1925: 🧹 Nitpick (assertive)

Simplify the clean_description method by removing unnecessary assignment.

The code creates a temporary variable that's immediately returned.

    def clean_description(self) -> str:
        description = self.cleaned_data.get("description", "")
-        return bleach.clean(
+        return bleach.clean(
             description,
             tags=self.ALLOWED_TAGS,
             attributes=self.ALLOWED_ATTRIBUTES,
             strip=True,
-        )
+        )

Likely an incorrect or invalid review comment.

Comment thread web/forms.py Outdated
Comment thread web/forms.py Outdated
Comment thread web/forms.py Outdated
@varruunnn
Copy link
Copy Markdown
Contributor Author

/gemini review

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 23, 2025
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new feature for requesting educational videos. The code includes models, forms, views, templates, and admin configurations. Overall, the code is well-structured and addresses the intended functionality. The use of bleach for input sanitization is a good security practice. However, there are some areas that could be improved, such as adding more comprehensive help text to the model fields and ensuring that the allowed tags and attributes for input sanitization are carefully considered.

Summary of Findings

  • Input Sanitization: The code implements input sanitization using the bleach library, which is good for preventing XSS attacks. However, it's important to ensure that the allowed tags and attributes are carefully chosen to balance security and functionality. Consider whether the current set of allowed tags and attributes is sufficient for the intended use case, and whether any potentially dangerous tags or attributes have been inadvertently allowed.
  • Model Field Help Text: The VideoRequest model includes help text for the title and description fields. It would be beneficial to add help text to the other fields in the model as well, such as category, requester, and status, to provide additional context and guidance to users interacting with the model in the admin interface.

Merge Readiness

The pull request is almost ready for merging. Before merging, it would be beneficial to address the medium severity issues related to the model field help text. I am unable to directly approve the pull request, and users should have others review and approve this code before merging.

Comment thread web/forms.py Outdated
Comment thread web/models.py
Comment thread web/models.py
Comment thread web/models.py
coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 23, 2025
@varruunnn
Copy link
Copy Markdown
Contributor Author

@gemini Which changes have not been made?

@gemini-code-assist
Copy link
Copy Markdown
Contributor

It appears you're asking me to identify which changes from the previous review haven't been incorporated in the current pull request. However, I don't have the capacity to retain the history of the previous review comments, and thus can't respond to your question. Apologies!

To get an accurate comparison, you might consider using GitHub's compare feature directly, or you can try re-running /gemini review to get a fresh review based on the current state of the PR.

@varruunnn
Copy link
Copy Markdown
Contributor Author

@A1L13N please check slack dm

@varruunnn
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the functionality for users to request educational videos. The implementation includes models, forms, views, templates, and admin configurations. Overall, the code is well-structured and addresses the intended feature. However, there are a few areas that could be improved for security and maintainability.

Summary of Findings

  • XSS Protection: The VideoRequestForm includes XSS protection using bleach. Ensure that the allowed tags and attributes are carefully reviewed to prevent potential bypasses.
  • Input Sanitization: The clean_title method in VideoRequestForm strips all tags and attributes. Consider whether this is too restrictive and if some basic formatting should be allowed.
  • Category Counts: The category counts in video_request_list view are retrieved using a dictionary comprehension. Consider using Counter for a more efficient and readable approach.

Merge Readiness

The pull request is almost ready for merging. However, I recommend addressing the XSS protection concerns and input sanitization in VideoRequestForm before merging. Also, consider the efficiency of category counts retrieval in video_request_list view. I am unable to approve this pull request, and recommend that others review and approve this code before merging.

Comment thread web/forms.py Outdated
Comment thread web/views.py Outdated
@A1L13N
Copy link
Copy Markdown
Contributor

A1L13N commented Apr 23, 2025

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the functionality for users to request educational videos. Overall, the code is well-structured and addresses the intended feature. However, there are a few areas that could be improved for better security and maintainability.

Summary of Findings

  • Input Sanitization: While the VideoRequestForm includes XSS protection using bleach, the clean_title method strips all tags and attributes, which might be too restrictive. Consider allowing a limited set of safe tags for titles as well.
  • Category Counts: The category counts in video_request_list are retrieved using a dictionary comprehension, which can be inefficient for large datasets. Consider using Django's aggregation features for better performance.

Merge Readiness

The pull request is almost ready for merging. Before merging, I recommend addressing the input sanitization issue by allowing a limited set of safe tags for titles. Also, consider improving the efficiency of category counts retrieval in video_request_list using Django's aggregation features. I am unable to approve this pull request, and recommend that others review and approve this code before merging.

Comment thread web/forms.py Outdated
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (8)
web/views.py (2)

7651-7666: The submit_video_request view is well implemented but missing type hints.

The function correctly requires authentication, handles form submission, associates the request with the logged-in user, and provides appropriate feedback.

-@login_required
-def submit_video_request(request):
+@login_required
+def submit_video_request(request: HttpRequest) -> HttpResponse:
🧰 Tools
🪛 Ruff (0.8.2)

7651-7651: Missing return type annotation for public function submit_video_request

(ANN201)


7651-7651: Missing type annotation for function argument request

(ANN001)


7617-7647: 🧹 Nitpick (assertive)

The video_request_list view implementation looks good but could benefit from optimization.

The view correctly implements listing video requests with category filtering and proper authentication checks. However, the category counts calculation could be more efficient by using Django's annotation and aggregation instead of iterating through each category with separate queries.

-    # Get category counts for sidebar
-    category_counts = {
-        category.slug: VideoRequest.objects.filter(category=category).count() for category in Subject.objects.all()
-    }
+    # Get category counts for sidebar
+    category_counts = dict(
+        VideoRequest.objects.values("category__name", "category__slug")
+        .annotate(count=Count("id"))
+        .values_list("category__slug", "count")
+    )

Also, add type hints to improve code quality:

-@login_required
-def video_request_list(request):
+@login_required
+def video_request_list(request: HttpRequest) -> HttpResponse:
🧰 Tools
🪛 Ruff (0.8.2)

7617-7617: Missing return type annotation for public function video_request_list

(ANN201)


7617-7617: Missing type annotation for function argument request

(ANN001)

web/models.py (3)

2936-2939: Add input sanitization for user-provided fields
Title and description are rendered back to users; implement sanitization to prevent XSS (e.g., using bleach.clean in a clean() method or via a ModelForm with validators).


2941-2950: 🧹 Nitpick (assertive)

Add help_text to the status field
Explain the workflow transitions for status (pending, approved, fulfilled, rejected) to aid admins:

-    status = models.CharField(
+    status = models.CharField(
         max_length=20,
         choices=[…],
         default="pending",
-    )
+        help_text="Current state of the video request",
+    )

2938-2939: 🧹 Nitpick (assertive)

Include help_text on relational fields for clarity in admin
Add contextual help_text to category and requester for better UX in the admin:

-    category = models.ForeignKey(Subject, on_delete=models.PROTECT, related_name="video_requests")
+    category = models.ForeignKey(
+        Subject,
+        on_delete=models.PROTECT,
+        related_name="video_requests",
+        help_text="Subject category for the requested video",
+    )
-    requester = models.ForeignKey(User, on_delete=models.CASCADE, related_name="video_requests")
+    requester = models.ForeignKey(
+        User,
+        on_delete=models.CASCADE,
+        related_name="video_requests",
+        help_text="User who initiated this video request",
+    )
web/forms.py (3)

1922-1929: 🧹 Nitpick (assertive)

Consider removing the assignment to a temporary variable.

The code creates a temporary variable cleaned, which is unnecessary since you return it immediately. You can return the result directly.

    def clean_description(self) -> str:
        description = self.cleaned_data.get("description", "")
        return bleach.clean(
            description,
            tags=self.ALLOWED_TAGS,
            attributes=self.ALLOWED_ATTRIBUTES,
            strip=True,
        )

1917-1920: 🧹 Nitpick (assertive)

Update comment to match implementation for title sanitization.

The comment states "Strip all tags" but the implementation actually allows the HTML tags defined in ALLOWED_TAGS. If the intention is to allow HTML formatting in titles, update the comment to reflect this. If the intention is to strip all tags, use empty lists for the tags and attributes parameters.

    def clean_title(self) -> str:
        title = self.cleaned_data.get("title", "")  # Added default value
-        # Strip all tags to ensure title contains only plain text
+        # Allow same HTML tags in title as in description for consistent formatting
        return bleach.clean(title, tags=self.ALLOWED_TAGS, attributes=self.ALLOWED_ATTRIBUTES, strip=True)

Or if you want to strip all tags:

    def clean_title(self) -> str:
        title = self.cleaned_data.get("title", "")  # Added default value
        # Strip all tags to ensure title contains only plain text
-        return bleach.clean(title, tags=self.ALLOWED_TAGS, attributes=self.ALLOWED_ATTRIBUTES, strip=True)
+        return bleach.clean(title, tags=[], attributes={}, strip=True)

1889-1911: 🧹 Nitpick (assertive)

Add missing trailing commas for better maintainability.

You've done a good job setting up the form widgets with appropriate styling and helpful placeholders. However, there are missing trailing commas that should be added for consistency and to make future modifications easier.

                    "placeholder": (
                        "Describe what you'd like to learn from this video "
-                       "(e.g., 'I'd like a video on calculus basics')"
+                       "(e.g., 'I'd like a video on calculus basics')",
                    ),
                }
            ),
            "category": TailwindSelect(
                attrs={
                    "class": (
                        "w-full px-4 py-2 border border-gray-300 dark:border-gray-600"
-                       " rounded-lg focus:ring-2 focus:ring-blue-500"
+                       " rounded-lg focus:ring-2 focus:ring-blue-500",
                    )
                }
            ),
🧰 Tools
🪛 Ruff (0.8.2)

1891-1891: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1892-1911: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1901-1901: Trailing comma missing

Add trailing comma

(COM812)


1908-1908: Trailing comma missing

Add trailing comma

(COM812)


1909-1909: Trailing comma missing

Add trailing comma

(COM812)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f26cd09 and f12d115.

📒 Files selected for processing (5)
  • web/forms.py (4 hunks)
  • web/models.py (1 hunks)
  • web/templates/base.html (2 hunks)
  • web/urls.py (1 hunks)
  • web/views.py (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
web/models.py (1)
Learnt from: A1L13N
PR: alphaonelabs/alphaonelabs-education-website#582
File: web/models.py:2932-2932
Timestamp: 2025-04-23T14:21:41.450Z
Learning: Django applications should implement input validation to prevent XSS attacks, using techniques such as Django forms with validators, model clean methods, security middleware, or specialized libraries like django-bleach.
🧬 Code Graph Analysis (2)
web/urls.py (1)
web/views.py (2)
  • video_request_list (7617-7647)
  • submit_video_request (7651-7665)
web/forms.py (2)
web/models.py (18)
  • VideoRequest (2933-2961)
  • Meta (45-46)
  • Meta (206-207)
  • Meta (403-404)
  • Meta (549-550)
  • Meta (605-606)
  • Meta (627-628)
  • Meta (681-684)
  • Meta (735-736)
  • Meta (788-790)
  • Meta (839-840)
  • Meta (879-881)
  • Meta (903-904)
  • Meta (922-923)
  • Meta (977-978)
  • Meta (1044-1045)
  • Meta (1075-1076)
  • Subject (197-215)
web/widgets.py (3)
  • TailwindInput (5-16)
  • TailwindTextarea (19-31)
  • TailwindSelect (62-73)
🪛 Ruff (0.8.2)
web/models.py

2952-2952: Trailing comma missing

Add trailing comma

(COM812)


2958-2958: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


2960-2960: Missing return type annotation for special method __str__

Add return type annotation: str

(ANN204)

web/forms.py

1891-1891: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1892-1911: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


1901-1901: Trailing comma missing

Add trailing comma

(COM812)


1908-1908: Trailing comma missing

Add trailing comma

(COM812)


1909-1909: Trailing comma missing

Add trailing comma

(COM812)

web/views.py

7617-7617: Missing return type annotation for public function video_request_list

(ANN201)


7617-7617: Missing type annotation for function argument request

(ANN001)


7651-7651: Missing return type annotation for public function submit_video_request

(ANN201)


7651-7651: Missing type annotation for function argument request

(ANN001)

🔇 Additional comments (5)
web/templates/base.html (2)

275-278: Navigation link for Video Requests looks good!

The new Video Requests link is properly integrated into the COMMUNITY dropdown menu with consistent styling and icon usage that matches the surrounding elements.


659-663: Mobile navigation matches desktop implementation correctly.

The Video Requests link has been properly added to the mobile menu with matching URL, text, and icon styling that's consistent with the desktop version.

web/urls.py (1)

128-130: URL patterns for video requests feature are well-structured.

The URL patterns follow the application's convention and properly separate the listing and submission functionality. Good job using the login_required decorator for the submission endpoint to ensure only authenticated users can submit requests.

I see these URLs connect to the views shown in the context, with video_request_list supporting category filtering and submit_video_request handling form submissions from authenticated users.

web/forms.py (2)

1880-1887: Nice implementation of XSS protection using bleach.

Good job defining the allowed tags and attributes as class constants with proper type annotations. The comment explaining the security reasoning for limited attributes on anchor tags is helpful for maintainability.


1913-1915: Good type annotations and query optimization.

You've correctly annotated the __init__ method with type hints and optimized the category queryset to be ordered by name, which improves the user experience.

Comment thread web/models.py
Comment thread web/models.py Outdated
Comment thread web/models.py
Comment thread web/models.py
coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 25, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
web/models.py (4)

2936-2937: Add input validation to prevent XSS attacks in text fields

The title and description fields should incorporate input validation to prevent XSS attacks.

According to your learnings, "Django applications should implement input validation to prevent XSS attacks, using techniques such as Django forms with validators, model clean methods, security middleware, or specialized libraries like django-bleach."


2941-2950: 🧹 Nitpick (assertive)

Add help text to the status field for admin clarity

Consider adding help text to the status field to explain each status option to administrators.

    status = models.CharField(
        max_length=20,
        choices=[
            ("pending", "Pending"),
            ("approved", "Approved"),
            ("fulfilled", "Fulfilled"),
            ("rejected", "Rejected"),
        ],
        default="pending",
+       help_text="Current processing status of the video request",
    )

2963-2963: 🧹 Nitpick (assertive)

Annotate mutable class attribute with ClassVar

The mutable class attribute ordering should be annotated with typing.ClassVar to satisfy static type checkers.

    class Meta:
        verbose_name = "Video Request"
        verbose_name_plural = "Video Requests"
-        ordering = ["-created_at"]
+        from typing import ClassVar
+        ordering: ClassVar[list[str]] = ["-created_at"]
🧰 Tools
🪛 Ruff (0.8.2)

2963-2963: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


2933-2966: 🛠️ Refactor suggestion

Add data validation to ensure status and fulfilled_by consistency

The model lacks validation to ensure that if status is "fulfilled", the fulfilled_by field must be populated (and vice versa). This could lead to inconsistent data.

Add a clean() method to enforce this business rule:

    def __str__(self) -> str:
        return self.title
+
+    def clean(self):
+        from django.core.exceptions import ValidationError
+        
+        if self.status == "fulfilled" and not self.fulfilled_by:
+            raise ValidationError({"fulfilled_by": "A fulfilled video must be specified when status is 'fulfilled'."})
+        if self.fulfilled_by and self.status != "fulfilled":
+            raise ValidationError({"status": "Status must be 'fulfilled' when a fulfilling video is assigned."})
+            
+    def save(self, *args, **kwargs):
+        self.full_clean()  # Force validation before saving
+        super().save(*args, **kwargs)
🧰 Tools
🪛 Ruff (0.8.2)

2963-2963: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f12d115 and 8f779b6.

📒 Files selected for processing (3)
  • web/migrations/0061_alter_educationalvideo_description_videorequest.py (1 hunks)
  • web/migrations/0062_alter_videorequest_fulfilled_by.py (1 hunks)
  • web/models.py (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
web/models.py (1)
Learnt from: A1L13N
PR: alphaonelabs/alphaonelabs-education-website#582
File: web/models.py:2932-2932
Timestamp: 2025-04-23T14:21:41.450Z
Learning: Django applications should implement input validation to prevent XSS attacks, using techniques such as Django forms with validators, model clean methods, security middleware, or specialized libraries like django-bleach.
🧬 Code Graph Analysis (2)
web/migrations/0062_alter_videorequest_fulfilled_by.py (1)
web/migrations/0061_alter_educationalvideo_description_videorequest.py (1)
  • Migration (8-75)
web/migrations/0061_alter_educationalvideo_description_videorequest.py (1)
web/migrations/0062_alter_videorequest_fulfilled_by.py (1)
  • Migration (7-19)
🪛 Ruff (0.8.2)
web/migrations/0062_alter_videorequest_fulfilled_by.py

9-11: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


13-19: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)

web/models.py

2963-2963: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)

web/migrations/0061_alter_educationalvideo_description_videorequest.py

10-13: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


15-75: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


47-47: Trailing comma missing

Add trailing comma

(COM812)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-and-test
  • GitHub Check: Run Tests
🔇 Additional comments (2)
web/migrations/0062_alter_videorequest_fulfilled_by.py (1)

7-19: Migration looks good - adds help text to fulfilled_by field

The migration correctly alters the VideoRequest model by adding helpful context to the fulfilled_by field without changing its essential behavior.

🧰 Tools
🪛 Ruff (0.8.2)

9-11: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


13-19: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)

web/migrations/0061_alter_educationalvideo_description_videorequest.py (1)

15-75: The VideoRequest model creation migration looks good

The migration successfully creates the VideoRequest model with appropriate fields, relationships and Meta options.

🧰 Tools
🪛 Ruff (0.8.2)

15-75: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


47-47: Trailing comma missing

Add trailing comma

(COM812)

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
web/migrations/0061_alter_educationalvideo_description_videorequest.py (1)

47-47: Add trailing comma for consistent style.

The ForeignKey definition is missing a trailing comma at the end of line 47.

                "category",
                models.ForeignKey(
-                   on_delete=django.db.models.deletion.PROTECT, related_name="video_requests", to="web.subject"
+                   on_delete=django.db.models.deletion.PROTECT, related_name="video_requests", to="web.subject",
                ),
🧰 Tools
🪛 Ruff (0.8.2)

47-47: Trailing comma missing

Add trailing comma

(COM812)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f779b6 and 76c2bd9.

📒 Files selected for processing (2)
  • web/migrations/0061_alter_educationalvideo_description_videorequest.py (1 hunks)
  • web/urls.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
web/migrations/0061_alter_educationalvideo_description_videorequest.py

10-13: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


15-76: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


47-47: Trailing comma missing

Add trailing comma

(COM812)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-and-test
  • GitHub Check: Run Tests
🔇 Additional comments (4)
web/urls.py (2)

128-130: LGTM! Video request URL patterns correctly implemented.

The new URL patterns for video requests follow Django best practices with clear naming and proper organization. The login_required decorator on the submission view correctly enforces authentication.


136-136: Good standardization of URL parameter naming.

Changing from <int:survey_id> to <int:pk> brings consistency with other survey URL patterns that use Django's conventional primary key parameter name.

web/migrations/0061_alter_educationalvideo_description_videorequest.py (2)

16-20: LGTM! Good improvement to the EducationalVideo model.

Making the description field optional with clear help text improves usability and clarifies the purpose of the field.


21-75: VideoRequest model looks well-designed.

The model has appropriate fields with helpful text, proper foreign key relationships, and good organization. The status choices are comprehensive, and the model options for ordering and verbose names are well-defined.

🧰 Tools
🪛 Ruff (0.8.2)

47-47: Trailing comma missing

Add trailing comma

(COM812)

@A1L13N
Copy link
Copy Markdown
Contributor

A1L13N commented Apr 25, 2025

Can we integrate this into the video view page so that users can see video requests on the right side and make a new request?

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 25, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (2)
web/views.py (2)

7659-7674: 🛠️ Refactor suggestion

Add type hints to submit_video_request view.

The view implementation is correct, but missing type hints which would improve code quality and maintainability.

-@login_required
-def submit_video_request(request):
+@login_required
+def submit_video_request(request: HttpRequest) -> HttpResponse:
    """View for submitting a new video request."""
    if request.method == "POST":
        form = VideoRequestForm(request.POST)
        if form.is_valid():
            video_request = form.save(commit=False)
            video_request.requester = request.user
            video_request.save()

            messages.success(request, "Your video request has been submitted successfully!")
            return redirect("video_request_list")
    else:
        form = VideoRequestForm()

    return render(request, "videos/submit_request.html", {"form": form})
🧰 Tools
🪛 Ruff (0.8.2)

7660-7660: Missing return type annotation for public function submit_video_request

(ANN201)


7660-7660: Missing type annotation for function argument request

(ANN001)


7625-7656: 💡 Verification agent

🧩 Analysis chain

Video request list view needs type hints and query optimization.

This new view for listing video requests is well-structured but has room for improvement with type hints and query optimization.

-def video_request_list(request):
+def video_request_list(request: HttpRequest) -> HttpResponse:
    """View for listing video requests with optional category filtering."""
    # Get category filter from query params
    selected_category = request.GET.get("category")

    # Base queryset
    requests = VideoRequest.objects.select_related("requester", "category").order_by("-created_at")

    # Apply category filter if provided
    if selected_category:
        requests = requests.filter(category__slug=selected_category)
        selected_category_obj = get_object_or_404(Subject, slug=selected_category)
        selected_category_display = selected_category_obj.name
    else:
        selected_category_display = None

    # Get category counts for sidebar
    category_counts = dict(
        VideoRequest.objects.values("category__slug")
        .annotate(count=Count("id"))
        .values_list("category__slug", "count"),
    )

To implement the above change, you'll need to add the import for Count:

from django.db.models import Count

🏁 Script executed:

#!/bin/bash
# Check if Count is already imported
grep -n "from django.db.models import" web/views.py

Length of output: 104


🏁 Script executed:

#!/bin/bash
# Check for HttpRequest and HttpResponse imports
grep -n "from django.http import" web/views.py || echo "No django.http imports found"

Length of output: 77


🏁 Script executed:

#!/bin/bash
# Display lines around the django.http import to verify HttpRequest and HttpResponse presence
grep -n "from django.http import" -A5 web/views.py

Length of output: 190


Add type hints and optimize category_counts in video_request_list

The video_request_list view can be enhanced with type hints and a single aggregated query for category counts to improve readability and performance.

File: web/views.py
Lines: where def video_request_list begins

Suggested changes:

-def video_request_list(request):
+def video_request_list(request: HttpRequest) -> HttpResponse:
     """View for listing video requests with optional category filtering."""
     # Get category filter from query params
@@
-    # Get category counts for sidebar
-    category_counts = {
-        category.slug: VideoRequest.objects.filter(category=category).count() for category in Subject.objects.all()
-    }
+    # Get category counts for sidebar (single aggregated query)
+    category_counts = dict(
+        VideoRequest.objects
+        .values("category__slug")
+        .annotate(count=Count("id"))
+        .values_list("category__slug", "count")
+    )

Notes:

  • Count, HttpRequest, and HttpResponse are already imported.
  • This change avoids an N+1 query when counting per category.
🧰 Tools
🪛 Ruff (0.8.2)

7626-7626: Missing return type annotation for public function video_request_list

(ANN201)


7626-7626: Missing type annotation for function argument request

(ANN001)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 76c2bd9 and 50edfea.

📒 Files selected for processing (4)
  • web/templates/base.html (1 hunks)
  • web/templates/videos/list.html (6 hunks)
  • web/templates/videos/request_list.html (1 hunks)
  • web/views.py (4 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
web/views.py

5153-5153: Missing return type annotation for public function educational_videos_list

(ANN201)


5153-5153: Missing type annotation for function argument request

(ANN001)


5161-5161: Trailing comma missing

Add trailing comma

(COM812)


7626-7626: Missing return type annotation for public function video_request_list

(ANN201)


7626-7626: Missing type annotation for function argument request

(ANN001)


7660-7660: Missing return type annotation for public function submit_video_request

(ANN201)


7660-7660: Missing type annotation for function argument request

(ANN001)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-and-test
  • GitHub Check: Run Tests
🔇 Additional comments (13)
web/templates/videos/list.html (6)

60-65: Added "View All Requests" link in the sidebar
This new link correctly points to the video request list page and respects styling conventions.


79-86: Top-level "Upload Video" button for authenticated users
The conditional user.is_authenticated ensures only logged-in users see the upload action in the header. This matches the sidebar behavior and improves UX.


139-142: Video title anchor markup is correct
The <a> tag now includes the hover color and transition classes and wraps video.title properly. Line breaks are acceptable in HTML templates.


174-175: Pagination controls
Your active and surrounding page link styling matches the rest of the site’s pagination. No issues detected.

Also applies to: 178-179


205-212: Empty state call-to-action is user-friendly
When there are no videos, inviting authenticated users to upload the first video is a nice touch.


215-264: Verify context variables for video requests pagination
You reference video_requests_paginated to conditionally render the "View all requests" link. Please confirm that the corresponding view sets video_requests_paginated (e.g., a Boolean flag or page count check) to avoid undefined-variable errors.

web/templates/videos/request_list.html (5)

1-6: Boilerplate extends and title block look good
The extends, load, and {% block title %} directives are correct and consistent.


11-19: Sidebar categories markup is solid
The category links correctly use selected_category to highlight the filter.


33-43: Header and "Request a Video" CTA
The header dynamically displays the category name, and the button points to the submission form. Good use of styling and semantics.


44-72: Rendering the list of requests
The loop over requests includes title, metadata, description, status badge, and conditional link to the fulfilling video. The badge classes are consistent with other templates.


77-85: Empty state with inviting CTA
When there are no requests, you provide a centered message and a clear call-to-action button. Nicely done.

web/views.py (2)

104-104: LGTM: Added VideoRequestForm import.

The import has been added in the correct location, properly grouped with other form imports.


172-172: LGTM: Added VideoRequest model import.

The model import is in the appropriate alphabetical location within the models import group.

Comment thread web/templates/base.html
Comment thread web/templates/videos/list.html
Comment thread web/templates/videos/list.html
Comment thread web/views.py Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
web/views.py (2)

7626-7657: 🛠️ Refactor suggestion

The video_request_list view implementation looks good but could be optimized.

The function correctly implements listing video requests with category filtering and provides appropriate context data for the template.

The category counts calculation makes a separate database query for each category, which is inefficient. Consider optimizing with Django's annotation and aggregation capabilities:

# Get category counts for sidebar
- category_counts = {
-     category.slug: VideoRequest.objects.filter(category=category).count() 
-     for category in Subject.objects.all()
- }
+ category_counts = dict(
+     VideoRequest.objects
+     .values("category__slug")
+     .annotate(count=Count("id"))
+     .values_list("category__slug", "count")
+ )

Also, add type hints for improved code quality:

- @login_required
- def video_request_list(request):
+ @login_required
+ def video_request_list(request: HttpRequest) -> HttpResponse:
🧰 Tools
🪛 Ruff (0.8.2)

7627-7627: Missing return type annotation for public function video_request_list

(ANN201)


7627-7627: Missing type annotation for function argument request

(ANN001)


7660-7676: 🧹 Nitpick (assertive)

The submit_video_request view is well implemented but missing type hints.

The function correctly requires authentication, handles form submission, associates the request with the logged-in user, and provides appropriate feedback.

Consider adding type hints for the function signature:

-@login_required
-def submit_video_request(request):
+@login_required
+def submit_video_request(request: HttpRequest) -> HttpResponse:
🧰 Tools
🪛 Ruff (0.8.2)

7661-7661: Missing return type annotation for public function submit_video_request

(ANN201)


7661-7661: Missing type annotation for function argument request

(ANN001)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 50edfea and a31f858.

📒 Files selected for processing (1)
  • web/views.py (4 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
web/views.py

5160-5160: Trailing comma missing

Add trailing comma

(COM812)


7627-7627: Missing return type annotation for public function video_request_list

(ANN201)


7627-7627: Missing type annotation for function argument request

(ANN001)


7661-7661: Missing return type annotation for public function submit_video_request

(ANN201)


7661-7661: Missing type annotation for function argument request

(ANN001)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build-and-test
  • GitHub Check: Run Tests

Comment thread web/views.py
coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 25, 2025
Copy link
Copy Markdown
Contributor

@A1L13N A1L13N left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add bleach to the poetry files

@A1L13N A1L13N added this pull request to the merge queue Apr 30, 2025
Merged via the queue into alphaonelabs:main with commit 91c222c Apr 30, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants