diff options
| author | Bobby <[email protected]> | 2024-12-21 00:46:45 -0500 |
|---|---|---|
| committer | Bobby <[email protected]> | 2024-12-21 00:46:45 -0500 |
| commit | b453706835fcb5fe960375c7101074f3bb9c1c7a (patch) | |
| tree | 34e3a2e9a6202c032c7703dc9adbb12f530aed70 /apps | |
| parent | 70bd8ebf6e0de202cb3a4f52f39766e69f146053 (diff) | |
| download | thatcomputerscientist-b453706835fcb5fe960375c7101074f3bb9c1c7a.tar.xz thatcomputerscientist-b453706835fcb5fe960375c7101074f3bb9c1c7a.zip | |
anime stream pages
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/anime/__init__.py | 0 | ||||
| -rw-r--r-- | apps/anime/admin.py | 3 | ||||
| -rw-r--r-- | apps/anime/apps.py | 6 | ||||
| -rw-r--r-- | apps/anime/migrations/__init__.py | 0 | ||||
| -rw-r--r-- | apps/anime/models.py | 3 | ||||
| -rw-r--r-- | apps/anime/tests.py | 3 | ||||
| -rw-r--r-- | apps/anime/urls.py | 10 | ||||
| -rw-r--r-- | apps/anime/views.py | 210 | ||||
| -rw-r--r-- | apps/journals/urls.py | 1 | ||||
| -rw-r--r-- | apps/journals/views.py | 15 |
10 files changed, 250 insertions, 1 deletions
diff --git a/apps/anime/__init__.py b/apps/anime/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/apps/anime/__init__.py diff --git a/apps/anime/admin.py b/apps/anime/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/apps/anime/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/apps/anime/apps.py b/apps/anime/apps.py new file mode 100644 index 00000000..9f6afd41 --- /dev/null +++ b/apps/anime/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AnimeConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "apps.anime" diff --git a/apps/anime/migrations/__init__.py b/apps/anime/migrations/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/apps/anime/migrations/__init__.py diff --git a/apps/anime/models.py b/apps/anime/models.py new file mode 100644 index 00000000..71a83623 --- /dev/null +++ b/apps/anime/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/apps/anime/tests.py b/apps/anime/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/apps/anime/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/apps/anime/urls.py b/apps/anime/urls.py new file mode 100644 index 00000000..d9b7b810 --- /dev/null +++ b/apps/anime/urls.py @@ -0,0 +1,10 @@ +from django.urls import path, re_path + +from . import views + +app_name = "anime" +urlpatterns = [ + path("", views.home, name="home"), + path("search/", views.search, name="search"), + re_path(r"^(?P<anime_id>\d+)(?:\.(?P<e>\d+))?/$", views.anime, name="anime"), +] diff --git a/apps/anime/views.py b/apps/anime/views.py new file mode 100644 index 00000000..6b976391 --- /dev/null +++ b/apps/anime/views.py @@ -0,0 +1,210 @@ +import os +from django.urls import reverse +import requests +from django.shortcuts import redirect, render + +from thatcomputerscientist.utils import i18npatterns + +genres = [ + "Action", + "Adventure", + "Cars", + "Comedy", + "Drama", + "Fantasy", + "Horror", + "Mahou Shoujo", + "Mecha", + "Music", + "Mystery", + "Psychological", + "Romance", + "Sci-Fi", + "Slice of Life", + "Sports", + "Supernatural", + "Thriller", +] + +sortings = [ + {"name": "Popularity", "value": "popularity"}, + {"name": "Trending", "value": "trending"}, + {"name": "Start Date", "value": "start_date"}, + {"name": "End Date", "value": "end_date"}, + {"name": "Score", "value": "score"}, + {"name": "Favourites", "value": "favourites"}, + {"name": "Title", "value": "title"}, +] + +ANIME_PROVIDER_MAP = {} + + +def get_anime(anime_id, dub=False): + if anime_id in ANIME_PROVIDER_MAP: + provider = ANIME_PROVIDER_MAP[anime_id] + else: + provider = "zoro" + + dub = "true" if dub else "false" + base_url = f"{os.getenv('CONSUMET_URL')}/meta/anilist/info/{anime_id}" + params = {"provider": provider, "dub": dub} + + response = requests.get(base_url, params=params) + data = response.json() + if ( + (not data.get("episodes") or len(data.get("episodes")) == 0) + and provider == "zoro" + and data.get("status") != "Not yet aired" + ): + ANIME_PROVIDER_MAP[anime_id] = "gogoanime" + return get_anime(anime_id) + else: + ANIME_PROVIDER_MAP[anime_id] = provider + return data + + +def sort_mapper(sort_by, order): + sort_mappings = { + "popularity": "POPULARITY", + "trending": "TRENDING", + "start_date": "START_DATE", + "end_date": "END_DATE", + "score": "SCORE", + "favourites": "FAVOURITES", + "title": "TITLE_ROMAJI", + } + + if sort_by not in sort_mappings or order not in ["asc", "desc"]: + return None + + sort_value = sort_mappings[sort_by] + order_suffix = "" if order == "asc" else "_DESC" + + return f"{sort_value}{order_suffix}" + + +def bracketed_string(string): + return f'["{string}"]' + + +def anime_results( + sort="trending", order="desc", genre="", query="", page=1, per_page=12, status="" +): + supported_status = [ + "releasing", + "not_yet_released", + "cancelled", + "finished", + "hiatus", + ] + + if status and status not in supported_status: + status = "" + + base_url = f"{os.getenv('CONSUMET_URL')}/meta/anilist/advanced-search" + params = {"page": page, "perPage": per_page, "type": "ANIME"} + + if query: + params["query"] = query + + if sort and order: + sort_value = sort_mapper(sort, order) + if sort_value: + params["sort"] = bracketed_string(sort_value) + + if genre: + params["genres"] = bracketed_string(genre) + + if status: + params["status"] = status.upper() + + response = requests.get(base_url, params=params) + return response.json() + + +def home(request): + META = { + "title": "Anime: Home", + } + LANGUAGE_CODE = i18npatterns(request.LANGUAGE_CODE) + request.meta.update(META) + + context = { + "genres": genres, + "sortings": sortings, + "trending_anime": anime_results(sort="trending", per_page=8), + "popular_anime": anime_results(sort="popularity", per_page=8), + "top_anime": anime_results(sort="score", per_page=8), + "top_airing_anime": anime_results( + sort="popularity", status="releasing", per_page=8 + ), + } + + return render(request, f"{LANGUAGE_CODE}/anime/home.html", context) + + +def search(request): + # Get search parameters + query = request.GET.get("q", "") + genre = request.GET.get("genre", "") + sort = request.GET.get("sort", "popularity") + order = request.GET.get("order", "desc") + page = int(request.GET.get("page", 1)) + + META = { + "title": f"Anime: Search", + } + if query: + META["title"] = f"Anime: Search Results for {query}" + LANGUAGE_CODE = i18npatterns(request.LANGUAGE_CODE) + request.meta.update(META) + + # Get search results + search_results = anime_results( + query=query, genre=genre, sort=sort, order=order, page=page, per_page=32 + ) + + context = { + "genres": genres, + "sortings": sortings, + "search_results": search_results, + "current_page": page, + "total_pages": search_results.get("totalPages", 1), + "total_results": search_results.get("totalResults", 0), + } + + return render(request, f"{LANGUAGE_CODE}/anime/search.html", context) + + +def anime(request, anime_id, e=None): + dub = request.COOKIES.get("anime_dub", False) + anime_data = get_anime(anime_id, dub) + + if len(anime_data.get("episodes")) > 0: + episode_numbers = [ + int(episode.get("number")) for episode in anime_data.get("episodes") + ] + + if not e: + e = episode_numbers[0] + return redirect( + reverse("anime:anime", kwargs={"anime_id": anime_id, "e": e}) + ) + + e = int(e) + if e not in episode_numbers: + return redirect( + reverse("anime:anime", kwargs={"anime_id": anime_id, "e": 1}) + ) + + META = { + "title": f"Anime: {anime_data.get('title').get('romaji')}", + } + LANGUAGE_CODE = i18npatterns(request.LANGUAGE_CODE) + request.meta.update(META) + + context = { + "anime": anime_data, + } + + return render(request, f"{LANGUAGE_CODE}/anime/anime.html", context) diff --git a/apps/journals/urls.py b/apps/journals/urls.py index b4e7db01..bc7155c3 100644 --- a/apps/journals/urls.py +++ b/apps/journals/urls.py @@ -4,5 +4,6 @@ from . import views app_name = "journal" urlpatterns = [ + path("", views.journal_of_random_thoughts, name="journal_of_random_thoughts"), path("<slug:slug>/", views.single_journal, name="single"), ] diff --git a/apps/journals/views.py b/apps/journals/views.py index 9c3f99f7..070c20b0 100644 --- a/apps/journals/views.py +++ b/apps/journals/views.py @@ -3,7 +3,20 @@ from apps.journals.models import Journal from thatcomputerscientist.utils import i18npatterns -# Create your views here. +def journal_of_random_thoughts(request): + META = { + "title": "Journal: Journal of Random Thoughts", + } + LANGUAGE_CODE = i18npatterns(request.LANGUAGE_CODE) + request.meta.update(META) + slug = "journal-of-random-thoughts" + journal = Journal.objects.get(slug=slug) + context = { + "journal": journal, + } + return render(request, f"{LANGUAGE_CODE}/journals/single.html", context) + + def single_journal(request, slug): try: journal = Journal.objects.get(slug=slug) |
