1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
# views.py
import os
import random
import re
from urllib.parse import quote, urljoin, urlparse
from django.conf import settings
from internal.crypto_utilities import decode_url, encode_url
from services.stream.songs import MUSIC_FILES
import requests
from django.http import (
HttpResponse,
HttpResponseForbidden,
JsonResponse,
StreamingHttpResponse,
)
CDN_URL = os.getenv("CDN_URL")
MUSIC_FILES_COUNT = len(MUSIC_FILES)
def get_stream_url(filename: str) -> str:
return f"{CDN_URL}/music/{filename}"
def random_song(request) -> JsonResponse:
next_song_id = request.GET.get("next")
if next_song_id:
song = MUSIC_FILES[int(next_song_id) % MUSIC_FILES_COUNT]
else:
song = random.choice(MUSIC_FILES)
return JsonResponse(song)
def stream_song(request, song_id: int) -> HttpResponse:
if not request.COOKIES.get("csrftoken"):
return HttpResponseForbidden("Invalid request")
referrer = request.META.get("HTTP_REFERER")
if not referrer:
return HttpResponseForbidden("Direct access not allowed")
parsed_uri = urlparse(referrer)
referrer_host = parsed_uri.netloc.split(":")[0]
if referrer_host not in settings.ALLOWED_HOSTS:
return HttpResponseForbidden("Access not allowed")
try:
song = MUSIC_FILES[song_id - 1]
stream_url = get_stream_url(song["songName"])
response = requests.get(stream_url, stream=True)
if response.status_code != 200:
return HttpResponse(status=response.status_code)
return HttpResponse(
response.raw.read(),
content_type=response.headers.get("Content-Type", "audio/mpeg"),
headers={
"Content-Disposition": f"attachment; filename={song['songName']}.mp3",
"X-Frame-Options": "DENY",
"X-Content-Type-Options": "nosniff",
},
)
except (IndexError, KeyError):
return HttpResponse(status=404)
except Exception:
return HttpResponse(status=500)
def anime_stream(request):
return handle_stream(request)
def track_stream(request):
return handle_stream(request, isTrack=True)
def handle_stream(request, isTrack=False):
if not request.user.is_authenticated:
return HttpResponseForbidden("Access not allowed")
url = request.GET.get("video_id") if not isTrack else request.GET.get("track_id")
url = decode_url(url)
if not str(url).endswith(".vtt"):
referrer = request.META.get("HTTP_REFERER")
if not referrer:
return HttpResponseForbidden()
parsed_uri = urlparse(referrer)
referrer_host = parsed_uri.netloc.split(":")[0]
if referrer_host not in settings.ALLOWED_HOSTS:
return HttpResponseForbidden()
if not url:
return HttpResponse("No URL provided", status=400)
try:
# Make the request to the target server
response = requests.get(
url,
stream=True,
headers={
"User-Agent": request.headers.get("User-Agent", ""),
"Referer": request.headers.get("Referer", ""),
"Origin": request.headers.get("Origin", ""),
},
)
content_type = response.headers.get("content-type", "")
# Handle M3U8 playlists
if "m3u8" in content_type or url.endswith(".m3u8"):
content = response.text
base_url = url.rsplit("/", 1)[0] + "/"
# Modify the playlist URLs to go through our proxy
modified_content = []
for line in content.splitlines():
if line.startswith("#"):
modified_content.append(line)
elif line.strip(): # Handle content lines (URLs)
# Handle both absolute and relative URLs
if not line.startswith("http"):
line = urljoin(base_url, line)
proxy_url = (
f"/services/stream/anime?video_id={quote(encode_url(line))}"
)
# proxy_url = f"/services/stream/anime?url={quote(line)}"
modified_content.append(proxy_url)
else:
modified_content.append(line)
return HttpResponse(
"\n".join(modified_content),
content_type="application/vnd.apple.mpegurl",
)
# Handle VTT files
elif url.endswith(".vtt"):
content = response.text
base_url = url.rsplit("/", 1)[0] + "/"
# Pattern to match both full URLs and relative paths with optional #xywh fragment
sprite_pattern = r'((?:https?://[^\s<>"]+?|[\w-]+\.(?:jpg|jpeg|png|webp))(?:#xywh=[\d,]+)?)'
def replace_url(match):
sprite_url = match.group(1)
# If it's not a full URL, join it with the base URL
if not sprite_url.startswith("http"):
sprite_url = urljoin(base_url, sprite_url)
return (
f"/services/stream/track?track_id={quote(encode_url(sprite_url))}"
)
# return f"/watch/stream?url={quote(sprite_url)}"
# Replace all image URLs with proxied versions
modified_content = re.sub(sprite_pattern, replace_url, content)
return HttpResponse(modified_content, content_type="text/vtt")
# Handle images (thumbnails)
elif any(ext in url.lower() for ext in [".jpg", ".jpeg", ".png", ".webp"]):
return StreamingHttpResponse(
response.iter_content(chunk_size=8192),
content_type=response.headers.get("content-type"),
status=response.status_code,
)
# For video segments and other content, stream directly
return StreamingHttpResponse(
response.iter_content(chunk_size=8192),
content_type=response.headers.get("content-type"),
status=response.status_code,
)
except requests.RequestException as e:
return HttpResponse(f"Error proxying request: {str(e)}", status=500)
|