init (pre-existing): added template oop implementation

This commit is contained in:
Emile Clark-Boman 2025-07-06 21:29:08 +10:00
commit d51238838c
13 changed files with 178 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
__pycache__/
venv/

13
NERD Normal file
View file

@ -0,0 +1,13 @@
Anime is found on providers
Providers *can* have multiple mirrors
Each mirror acts the same
Each mirror provides anime
Each anime has episodes
To create an object oriented design I plan to reverse this and focus
around an `Anime` object. This object will reference which mirrors
supply it and etc. TODO: (fill this out more)
NOTE: We can ping each mirror to estimate which is best to stream from.

6
README Normal file
View file

@ -0,0 +1,6 @@
Watch anime from your terminal!!
But smarter than ani-cli! Eva remembers where you're up to and let's you jump straight back into the funny japanese cartoons!
Also shows you trending animes, and the release schedules for new episodes!
(https://animeschedule.net)

54
UWU Normal file
View file

@ -0,0 +1,54 @@
### Aspects
Ok so theres quite a few parts to this project.
I've ordered them based on the order I plan to implement them:
1. Searching providers for pages based on a query
2. Turning provider pages (above) into a python object with all relevant details using regex
3. Fetching a streaming link
4. Downloading an anime instead of streaming
5. Displaying in the current terminal (most likely with mpv)
6. Displaying a TUI interface
7. Allowing intros to be skipped
3. (Optional) A settings option that automatically translates anime names to English
Start by targetting HiAnime
###### Which Providers to Use
This is the best possible list of sites
https://everythingmoe.com/
This is a pretty good overview too
https://www.reddit.com/r/animepiracy/comments/myfhk9/result_of_testing_every_website_on_animepiracy/
###### Skipping Intros
I could either design my own system for this by looking at the frames and looking for
extremely similar segments.
OR
I could check out this project:
https://github.com/jonbarrow/open-anime-timestamps
Open anime stamps developer talks [here](https://www.reddit.com/r/animepiracy/comments/oo1gbm/open_anime_timestamps_anime_openingending/) about how
it uses "acoustic fingerprinting" to detect timings! (sooooo cool)
###### Related Anime
Also check out how cool this is:
https://anidb.net/anime/16951/relation/graph
They can provide relation graphs between animes (mind blown)
##### Changing Subtitle Language
Maybe I could have something that automatically translates an episode's
subtitles into another language?

1
activate-venv Normal file
View file

@ -0,0 +1 @@
source ./venv/bin/activate.fish

1
requirements.txt Normal file
View file

@ -0,0 +1 @@
requests

0
src/core/__init__.py Normal file
View file

3
src/core/mirror.py Normal file
View file

@ -0,0 +1,3 @@
class Mirror:
def __init__(self, url: str) -> None:
self.url = url

11
src/core/provider.py Normal file
View file

@ -0,0 +1,11 @@
from core.mirror import Mirror
'''
A provider can have multiple mirrors
'''
class Provider:
name = 'ProviderTemplate'
def __init__(self) -> None:
pass
def GetMirrors(self) -> list[str]:
raise NotImplementedError(f'method GetMirrors not implemented for {self.name} inheriting from Provider')

View file

45
src/providers/hianime.py Normal file
View file

@ -0,0 +1,45 @@
# Dependencies
import re
import requests
from urllib.parse import quote_plus as urlencode
# Assets
from core.provider import Provider
search_expr = '<a href="([^"]+)" title="[^"]+" class="dynamic-name" data-jname="[^"]+"'
search_expr2 = ('<div class="flw-item">\s*'
'<div class="film-poster">\s*')
#'<div class="film-detail">.+</div>\s*'
#'<div class="clearfix">.+\s*'
#'</div>\s*'
#'</div>')
class hianime(Provider):
_NAME = 'HiAnime'
_BOOTSTRAP = 'https://hianime.tv'
def __init__(self) -> None:
pass
def GetMirrors(self) -> list[str]:
content = requests.get('https://hianime.tv').text
expr = '<a href="([a-z\./:]+)" title="">'
# for some reason hianime doesn't advertise `hianime.to` as a mirror
matches = re.findall(expr, content)
if 'https://hianime.to' not in matches:
matches.append('https://hianime.to')
return matches
def SearchAnime(self, mirror: str, query: str) -> list[str]: #-> list[Anime]:
urlsafe_query = urlencode(query)
url = f'{mirror}/search?keyword={urlsafe_query}&sort=default'
content = requests.get(url).text
#print(content)
matches = re.findall(search_expr, content)
return matches

30
src/test.py Normal file
View file

@ -0,0 +1,30 @@
from providers.hianime import hianime
from requests import async
def main():
provider = hianime()
mirrors = provider.GetMirrors()
#print(mirrors)
mirror = mirrors[0]
tasks = []
animes = provider.SearchAnime(mirror, 'blue lock')
print(len(animes))
for result in animes:
print(result)
result = mirror + result
new_task = async.get(result)
tasks.append(new_task)
# wait for tasks
async.map(tasks)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass

12
src/util/speedtest.py Normal file
View file

@ -0,0 +1,12 @@
from core.mirror import Mirror
'''
Speedtest multiple mirrors to see which is faster
My idea is to run some bash thing like
ping hianime.nz -c 1 -q | head -n 1
And then run one of those asyncronyously (in parallel)
for each mirror we're testing
'''
def Speedtest(mirrors: list[Mirror]) -> list[int]:
pass