aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2024-09-21 02:38:06 -0400
committerBobby <[email protected]>2024-09-21 02:38:06 -0400
commit12f85fd1fcb223bd3e62c7b352ccb57d4922fc0b (patch)
tree8ac25c738a029de64bde2f5e31902061153849b6
parentaa6bd3d74961a4950dab9167159540939bef45f2 (diff)
downloadyugen-12f85fd1fcb223bd3e62c7b352ccb57d4922fc0b.tar.xz
yugen-12f85fd1fcb223bd3e62c7b352ccb57d4922fc0b.zip
Provider Selection
-rw-r--r--detail/views.py7
-rw-r--r--static/css/main.css4
-rw-r--r--templates/watch/watch.html23
-rw-r--r--watch/utils.py162
-rw-r--r--watch/views.py15
5 files changed, 147 insertions, 64 deletions
diff --git a/detail/views.py b/detail/views.py
index b38471c..fdbb5a5 100644
--- a/detail/views.py
+++ b/detail/views.py
@@ -1,6 +1,6 @@
from django.shortcuts import redirect, render
from authentication.utils import get_single_anime_mal
-from watch.utils import attach_episode_metadata, get_anime_data, get_anime_episodes
+from watch.utils import attach_episode_metadata, get_anime_data, get_anime_episodes, get_anime_episodes_gogo
from watch.views import get_seasons_by_zid
@@ -8,11 +8,14 @@ def index(request):
return redirect("home:index")
def detail(request, anime_id):
- anime_data, provider = get_anime_data(anime_id)
+ anime_data, provider, gd = get_anime_data(anime_id)
if not anime_data:
return render(request, "detail/detail.html", {"error": "Anime not found"}, status=404)
anime_episodes = get_anime_episodes(anime_id)
+ if "message" in anime_episodes:
+ anime_data, provider, gd = get_anime_data(anime_id, provider="gogo")
+ anime_episodes, _ = get_anime_episodes_gogo(anime_id)
if anime_episodes:
attach_episode_metadata(anime_data, anime_episodes)
diff --git a/static/css/main.css b/static/css/main.css
index b45f803..3c8ae82 100644
--- a/static/css/main.css
+++ b/static/css/main.css
@@ -759,6 +759,10 @@ video {
margin-left: 1rem;
}
+.ml-8 {
+ margin-left: 2rem;
+}
+
.mr-1 {
margin-right: 0.25rem;
}
diff --git a/templates/watch/watch.html b/templates/watch/watch.html
index 0d086c3..20d0ce3 100644
--- a/templates/watch/watch.html
+++ b/templates/watch/watch.html
@@ -28,7 +28,7 @@
<div class="flex flex-col gap-2 h-full max-h-96 lg:h-[39vw] lg:max-h-[761px] overflow-y-auto">
{% for episode in all_episodes %}
{% if not viaMal and episode.number == current_episode_number or viaMal and episode.episode.number == current_episode_number %}
- <a id="selected-episode" href="{% if not viaMal %}{% url "watch:watch_episode" anime.id episode.number %}{% if request.GET.mode %}?mode={{ request.GET.mode }}{% endif %}{% else %}{% url "watch:watch_via_zid_mal_id" anime.id anime.z_anime_id %}?ep={{ episode.episode.identifier }}{% if request.GET.mode %}&mode={{ request.GET.mode }}{% endif %}{% endif %}" class="flex flex-row gap-4 justify-between items-center w-full bg-{{ user.preferences.accent_colour }}-600 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
+ <a id="selected-episode" href="{% if not viaMal %}{% url "watch:watch_episode" anime.id episode.number %}{% if request.GET.mode %}?mode={{ request.GET.mode }}{% endif %}{% if request.GET.mode and request.GET.provider %}&provider={{ request.GET.provider }}{% elif request.GET.provider %}?provider={{ request.GET.provider }}{% endif %}{% else %}{% url "watch:watch_via_zid_mal_id" anime.id anime.z_anime_id %}?ep={{ episode.episode.identifier }}{% if request.GET.mode %}&mode={{ request.GET.mode }}{% endif %}{% if request.GET.mode and request.GET.provider %}&provider={{ request.GET.provider }}{% elif request.GET.provider %}?provider={{ request.GET.provider }}{% endif %}{% endif %}" class="flex flex-row gap-4 justify-between items-center w-full bg-{{ user.preferences.accent_colour }}-600 p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
<span class="truncate max-w-full overflow-hidden text-ellipsis whitespace-nowrap">{{ episode.number }}. {{ episode.title }}</span>
<span class="flex flex-row item-center gap-2">
@@ -62,7 +62,7 @@
</a>
{% else %}
- <a href="{% if not viaMal %}{% url "watch:watch_episode" anime.id episode.number %}{% if request.GET.mode %}?mode={{ request.GET.mode }}{% endif %}{% else %}{% url "watch:watch_via_zid_mal_id" anime.id anime.z_anime_id %}?ep={{ episode.episode.identifier }}{% if request.GET.mode %}&mode={{ request.GET.mode }}{% endif %}{% endif %}" class="flex flex-row justify-between w-full gap-4 {% if episode.number in watched_episodes %}bg-{{ user.preferences.accent_colour }}-600 bg-opacity-20{% else %}bg-white bg-opacity-10{% endif %} p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
+ <a href="{% if not viaMal %}{% url "watch:watch_episode" anime.id episode.number %}{% if request.GET.mode %}?mode={{ request.GET.mode }}{% endif %}{% if request.GET.mode and request.GET.provider %}&provider={{ request.GET.provider }}{% elif request.GET.provider %}?provider={{ request.GET.provider }}{% endif %}{% else %}{% url "watch:watch_via_zid_mal_id" anime.id anime.z_anime_id %}?ep={{ episode.episode.identifier }}{% if request.GET.mode %}&mode={{ request.GET.mode }}{% endif %}{% if request.GET.mode and request.GET.provider %}&provider={{ request.GET.provider }}{% elif request.GET.provider %}?provider={{ request.GET.provider }}{% endif %}{% endif %}" class="flex flex-row justify-between w-full gap-4 {% if episode.number in watched_episodes %}bg-{{ user.preferences.accent_colour }}-600 bg-opacity-20{% else %}bg-white bg-opacity-10{% endif %} p-2 rounded hover:bg-{{ user.preferences.accent_colour }}-600 hover:bg-opacity-30">
<span class="truncate max-w-full overflow-hidden text-ellipsis whitespace-nowrap">{{ episode.number }}. {{ episode.title }}</span>
<span class="flex flex-row item-center gap-2">
{% if episode.filler %}
@@ -106,9 +106,22 @@
<div class="flex flex-row gap-2 items-center justify-between">
{% if current_episode %}<h2 class="text-xl font-bold truncate max-w-full overflow-hidden text-ellipsis whitespace-nowrap">Episode {{ current_episode.number }} — {{ current_episode.title }}</h2>{% endif %}
<div class="flex flex-row gap-1 items-center">
+ <span class="font-bold">Episode Provider: </span>
+ <a href="{% if not viaMal %}
+ {% url "watch:watch_episode" anime.id current_episode.number %}?mode={{ mode }}&provider=zoro
+ {% else %}
+ {% url "watch:watch_via_zid_mal_id" anime.id anime.z_anime_id %}?ep={{ current_episode.episode.identifier }}&mode={{ mode }}&provider=zoro
+ {% endif %}" class="{% if provider == "zoro" %}bg-{{ user.preferences.accent_colour }}-600{% else %}bg-white bg-opacity-10{% endif %} text-white text-sm font-bold px-4 py-2 rounded">Zoro</a>
+
+ <a href="{% if not viaMal %}
+ {% url "watch:watch_episode" anime.id current_episode.number %}?mode={{ mode }}&provider=gogo
+ {% else %}
+ {% url "watch:watch_via_zid_mal_id" anime.id anime.z_anime_id %}?ep={{ current_episode.episode.identifier }}&mode={{ mode }}&provider=gogo
+ {% endif %}" class="{% if provider == "gogo" %}bg-{{ user.preferences.accent_colour }}-600{% else %}bg-white bg-opacity-10{% endif %} text-white text-sm font-bold px-4 py-2 rounded">Gogo</a>
+ <span class="ml-8 font-bold">Mode: </span>
{% if current_episode.number %}
- <a href="{% if not viaMal %}{% url "watch:watch_episode" anime.id current_episode.number %}?mode=sub{% else %}{% url "watch:watch_via_zid_mal_id" anime.id anime.z_anime_id %}?ep={{ current_episode.episode.identifier }}&mode=sub{% endif %}" class="{% if mode == "sub" %}bg-{{ user.preferences.accent_colour }}-600{% else %}bg-white bg-opacity-10{% endif %} text-white text-sm font-bold px-4 py-2 rounded">Sub</a>
- <a href="{% if not viaMal %}{% url "watch:watch_episode" anime.id current_episode.number %}?mode=dub{% else %}{% url "watch:watch_via_zid_mal_id" anime.id anime.z_anime_id %}?ep={{ current_episode.episode.identifier }}&mode=dub{% endif %}" class="{% if mode == "dub" %}bg-{{ user.preferences.accent_colour }}-600{% else %}bg-white bg-opacity-10{% endif %} text-white text-sm font-bold px-4 py-2 rounded">Dub</a>
+ <a href="{% if not viaMal %}{% url "watch:watch_episode" anime.id current_episode.number %}?mode=sub&provider={{ provider }}{% else %}{% url "watch:watch_via_zid_mal_id" anime.id anime.z_anime_id %}?ep={{ current_episode.episode.identifier }}&mode=sub&provider={{ provider }}{% endif %}" class="{% if mode == "sub" %}bg-{{ user.preferences.accent_colour }}-600{% else %}bg-white bg-opacity-10{% endif %} text-white text-sm font-bold px-4 py-2 rounded">Sub</a>
+ <a href="{% if not viaMal %}{% url "watch:watch_episode" anime.id current_episode.number %}?mode=dub&provider={{ provider }}{% else %}{% url "watch:watch_via_zid_mal_id" anime.id anime.z_anime_id %}?ep={{ current_episode.episode.identifier }}&mode=dub&provider={{ provider }}{% endif %}" class="{% if mode == "dub" %}bg-{{ user.preferences.accent_colour }}-600{% else %}bg-white bg-opacity-10{% endif %} text-white text-sm font-bold px-4 py-2 rounded">Dub</a>
{% endif %}
</div>
</div>
@@ -1095,7 +1108,7 @@
}, 30000);
{% endif %}
- {% if anime.totalEpisodes > current_episode_number and animeId %}
+ {% if should_preload %}
// If current episode is less than total episodes, preload the next episode
const nextEpisode = {{ current_episode_number }} + 1;
let nextEpisodeUrl = window.location.href.replace(`/watch/{{animeID}}/{{ current_episode_number }}`, `/watch/{{animeID}}/${nextEpisode}`);
diff --git a/watch/utils.py b/watch/utils.py
index 0a30329..339ef4e 100644
--- a/watch/utils.py
+++ b/watch/utils.py
@@ -16,8 +16,8 @@ r = redis.Redis(
password=os.getenv("REDIS_PASSWORD"),
)
-r.flushall()
-print("Redis cache flushed")
+# r.flushall()
+# print("Redis cache flushed")
def get_episode_metadata(anime_data, episode):
episode_metadata = get_all_episode_metadata(anime_data)
@@ -25,75 +25,131 @@ def get_episode_metadata(anime_data, episode):
return current_episode_metadata
@lru_cache(maxsize=100)
-def get_anime_data(anime_id):
- cache_key = f"anime_{anime_id}_anime_data"
+def get_anime_data(anime_id, provider="zoro", gogodub=False):
+ cache_key = f"anime_{anime_id}_anime_data_{provider}"
anime_data = get_from_redis_cache(cache_key)
- provider = get_from_redis_cache(f"anime_{anime_id}_provider")
- if not provider:
- provider = "zoro"
+ if provider == "gogo":
+ provider = "gogoanime"
+ print("anime data got provider=>", provider)
+ if gogodub:
+ print("anime data got dub=>", gogodub)
+ cache_key = f"anime_{anime_id}_anime_data_{provider}_dub"
if not anime_data:
- base_url = f"{os.getenv('CONSUMET_URL')}/meta/anilist/info/{anime_id}?provider=zoro"
- try:
- response = requests.get(base_url, timeout=10)
- anime_data = response.json()
- if ("message" not in anime_data or response.status_code == 200) and anime_data["episodes"]:
- if anime_data["status"] == "Completed":
- store_in_redis_cache(cache_key, json.dumps(anime_data), 3600 * 24 * 30) # Cache for 30 days
- else:
- store_in_redis_cache(cache_key, json.dumps(anime_data), 3600 * 12) # Cache for 12 hours
- store_in_redis_cache(f"anime_{anime_id}_provider", "zoro")
+ base_url = f"{os.getenv('CONSUMET_URL')}/meta/anilist/info/{anime_id}?provider={provider}"
+ if gogodub:
+ print("gogodub passed")
+ base_url += "&dub=true"
+ print("base_url=>", base_url)
+ response = requests.get(base_url, timeout=10)
+ anime_data = response.json()
+
+ print(f"Fetched {len(anime_data["episodes"])} episodes for ID {anime_id} with provider {provider} and dub=>{gogodub}")
+
+ if ("message" not in anime_data or response.status_code == 200) and anime_data["episodes"]:
+ if anime_data["status"] == "Completed":
+ store_in_redis_cache(cache_key, json.dumps(anime_data), 3600 * 24 * 30)
else:
- provider = "gogo"
- base_url = f"{os.getenv('CONSUMET_URL')}/meta/anilist/info/{anime_id}"
- response = requests.get(base_url, timeout=10)
- anime_data = response.json()
- store_in_redis_cache(cache_key, json.dumps(anime_data), 3600 * 12) # Cache for 12 hours
- store_in_redis_cache(f"anime_{anime_id}_provider", "gogo")
- except requests.RequestException as e:
- print(f"Error fetching anime data for ID {anime_id}: {e}")
- return None
+ store_in_redis_cache(cache_key, json.dumps(anime_data), 3600 * 12)
+ print(f"Anime data found for ID {anime_id} with provider {provider}, dub=>{gogodub}, episodes=>{len(anime_data['episodes'])}")
+ else:
+ provider = "gogo"
+ return get_anime_data(anime_id, provider, gogodub)
else:
anime_data = json.loads(anime_data)
if not anime_data:
print(f"Anime data not found for ID {anime_id}")
-
- return anime_data, provider
+ if provider == "gogoanime":
+ provider = "gogo"
+
+ return anime_data, provider, gogodub
@lru_cache(maxsize=100)
-def get_anime_episodes(anime_id):
- cache_key = f"anime_{anime_id}_anime_episodes"
+def get_anime_episodes(anime_id): #only returns episodes from zoro
+ cache_key = f"anime_{anime_id}_anime_episodes_zoro"
anime_episodes = get_from_redis_cache(cache_key)
-
+
if not anime_episodes:
- anime_data, provider = get_anime_data(anime_id)
+ anime_data, provider, gd = get_anime_data(anime_id, "zoro")
if not anime_data or not anime_data.get("episodes"):
return None
-
- if provider == "zoro":
- if "mappings" in anime_data:
- z_anime_id = next((m["id"] for m in anime_data["mappings"] if m["providerId"] == "zoro"), None)
- z_anime_id = z_anime_id.split("/")[-1] if z_anime_id else None
- else:
- z_anime_id = anime_data["episodes"][0]["id"].split("$")[0]
-
- print(f"Fetching episodes for ID {anime_id} with Zoro ID {z_anime_id}")
-
- base_url = f"{os.getenv('ZORO_URL')}/anime/episodes/{z_anime_id}"
- try:
- response = requests.get(base_url, timeout=10)
- anime_episodes = response.json()
- store_in_redis_cache(cache_key, json.dumps(anime_episodes), 86400) # Cache for 24 hours
- except requests.RequestException as e:
- print(f"Error fetching anime episodes for ID {anime_id}: {e}")
- return None
- else:
- return {"episodes": anime_data["episodes"], "totalEpisodes": len(anime_data["episodes"])}
+
+ z_anime_id = anime_data["episodes"][0]["id"].split("$")[0]
+
+ print(f"Fetching episodes for ID {anime_id} with Zoro ID {z_anime_id}")
+
+ base_url = f"{os.getenv('CONSUMET_URL')}/meta/zoro/anime/episodes/{z_anime_id}"
+ try:
+ response = requests.get(base_url, timeout=10)
+ anime_episodes = response.json()
+ store_in_redis_cache(cache_key, json.dumps(anime_episodes), 86400) # Cache for 24 hours
+ except requests.RequestException as e:
+ print(f"Error fetching anime episodes for ID {anime_id}: {e}")
+ return None
else:
anime_episodes = json.loads(anime_episodes)
-
+
return anime_episodes
+@lru_cache(maxsize=100)
+def get_anime_episodes_gogo(anime_id, mode="sub"):
+ cache_key = f"anime_{anime_id}_anime_episodes_gogo_{mode}"
+ anime_episodes = get_from_redis_cache(cache_key)
+
+ if not anime_episodes:
+ gogodub = True if mode == "dub" else False
+ print(f"Fetching episodes for ID {anime_id} with mode {mode} and dub=>{gogodub}")
+ anime_data, provider, gd = get_anime_data(anime_id, "gogo", gogodub)
+ anime_episodes = anime_data["episodes"]
+
+ store_in_redis_cache(cache_key, json.dumps(anime_episodes), 86400)
+ else:
+ anime_episodes = json.loads(anime_episodes)
+
+ anime_episode_data = {
+ "episodes": anime_episodes,
+ "totalEpisodes": len(anime_episodes)
+ }
+
+ print(f"Returning {len(anime_episodes)} episodes for ID {anime_id} with mode {mode}")
+
+ return anime_episode_data, mode
+
+
+# @lru_cache(maxsize=100)
+# def get_anime_episodes(anime_id, provider="zoro"):
+# cache_key = f"anime_{anime_id}_anime_episodes_{provider}"
+# anime_episodes = get_from_redis_cache(cache_key)
+
+# if not anime_episodes:
+# anime_data, provider = get_anime_data(anime_id, provider)
+# if not anime_data or not anime_data.get("episodes"):
+# return None
+
+# if provider == "zoro":
+# if "mappings" in anime_data:
+# z_anime_id = next((m["id"] for m in anime_data["mappings"] if m["providerId"] == "zoro"), None)
+# z_anime_id = z_anime_id.split("/")[-1] if z_anime_id else None
+# else:
+# z_anime_id = anime_data["episodes"][0]["id"].split("$")[0]
+
+# print(f"Fetching episodes for ID {anime_id} with Zoro ID {z_anime_id}")
+
+# base_url = f"{os.getenv('ZORO_URL')}/anime/episodes/{z_anime_id}"
+# try:
+# response = requests.get(base_url, timeout=10)
+# anime_episodes = response.json()
+# store_in_redis_cache(cache_key, json.dumps(anime_episodes), 86400) # Cache for 24 hours
+# except requests.RequestException as e:
+# print(f"Error fetching anime episodes for ID {anime_id}: {e}")
+# return None
+# else:
+# return {"episodes": anime_data["episodes"], "totalEpisodes": len(anime_data["episodes"])}
+# else:
+# anime_episodes = json.loads(anime_episodes)
+
+# return anime_episodes
+
def attach_episode_metadata(anime_data, anime_episodes):
anime_episodes_metadata = get_all_episode_metadata(anime_data)
if anime_episodes_metadata:
diff --git a/watch/views.py b/watch/views.py
index 1864df9..291fe8b 100644
--- a/watch/views.py
+++ b/watch/views.py
@@ -9,7 +9,7 @@ import requests
from authentication.utils import get_single_anime_mal
from user_profile.models import UserHistory
from watch.tmdbmapper import parse_title_and_season
-from watch.utils import attach_episode_metadata, get_anime_episodes, get_all_episode_metadata, get_anime_data, get_episodes_by_zid, get_from_redis_cache, get_info_by_zid, get_seasons_by_zid, store_in_redis_cache, update_anime_user_history, get_anime_user_history
+from watch.utils import attach_episode_metadata, get_anime_episodes_gogo, get_all_episode_metadata, get_anime_data, get_episodes_by_zid, get_from_redis_cache, get_info_by_zid, get_seasons_by_zid, store_in_redis_cache, update_anime_user_history, get_anime_user_history
from watch.models import Anime, AnimeEpisode, AnimeTitle, AnimeTrailer, AnimeGenre, AnimeStudio
from django.db import transaction
from authentication.models import User
@@ -333,8 +333,10 @@ def watch(request, anime_id, episode=None):
if not episode and request.user.preferences.default_watch_page == "detail" and not forward_detail:
return redirect("detail:detail", anime_id=anime_id)
- anime_fetched, provider = get_anime_data(anime_id)
+ anime_fetched, provider, gogodub = get_anime_data(anime_id)
provider = provider.decode() if isinstance(provider, bytes) else provider
+
+ provider = request.GET.get("provider", provider)
if anime_fetched["status"] == "Not yet aired":
return redirect("detail:detail", anime_id=anime_id)
@@ -408,12 +410,14 @@ def watch(request, anime_id, episode=None):
seasons = get_seasons_by_zid(anime.z_anime_id)
stream_url = streaming_data["sources"][0]["url"] if streaming_data and "sources" in streaming_data else None
else:
- episodes = get_anime_episodes(anime_id)
+ episodes, m = get_anime_episodes_gogo(anime_id, mode)
if episodes:
attach_episode_metadata(anime_fetched, episodes)
+ if not gogodub and mode == "dub":
+ print("Dub not available, fallback to sub")
+ mode = "sub"
episodes = episodes["episodes"]
episode_data = next((e for e in episodes if e["number"] == int(episode)), None)
- mode = "sub"
seasons = []
streaming_data = get_gogo_streaming_data(episode_data["id"]) if episode_data else None
streaming_data["anilistID"] = anime_id
@@ -423,6 +427,8 @@ def watch(request, anime_id, episode=None):
if preload_request:
return JsonResponse({"status": f"Preloaded episode {episode}"})
+
+ should_preload = episode < len(episodes)
context = {
"anime": anime,
@@ -440,6 +446,7 @@ def watch(request, anime_id, episode=None):
"current_watched_time": current_watched_time,
"seasons": seasons,
"provider": provider,
+ "should_preload": should_preload,
}
if provider == "zoro" and request.user.mal_access_token and anime.malId: