Package: jutsu-api
Jutsu APISimple and flexible API forjut.su.As a weeb, I have my own favourite site for watching anime.
Now that I am also a super h4ck3r, I created an API
for accessing this site and it turned out pretty well.InstallationInstall the module from PyPi:pip install jutsu-apiThen import it just like that:fromjutsu_apiimportAPIDocumentationAPIAPI(verbosity:int=0)ClassAPIis a singleton and can be initialized with
one parameterverbosity, which is responsible on how
much feedback the API sends. The feedback is being printed to stderr,
the default verbosity level is0.API.verbosity().verbosity(v:int)Set vebosity level explicitly.API.search().search(keyword:str="",filter:Filter=Filter(),maxpage:int=-1)->list[Anime]Searches the site for anime with given keyword and filter.
TheFilterobject is explained later.maxpageparameter is used to limit the output by stopping
parsing after an amount of pages.-1is the default value,
and means that there should be no limitation. A list ofAnimeobjects is returned. If there are no results, the list will be empty.API.anime().anime(id:str)->AnimeReturnsAnimeobject generated by parsing theidof that anime.
Anime's id is used and can be found in the link to the anime.Exampleid:stein-gateAPI.episode().episode(id:str)->EpisodeReturns a singleEpisodeobject generated by parsing theidof that episode.
Episode's id is the path link to the episode.Exampleid:stein-gate/season-1/episode-1.htmlAnimeAnime(name:Name|None=None,thumbnail:str|None=None,info:Filter|None=None,years:list[int]|None=None,age:int|None=None,description:str|None=None,content:Content|None=None,ongoing:bool|None=None,id:str|None=None)ClassAnimeprovides a full information about the selected anime.
Parsing anime fromAPI.search()does not give full information,
therefore some parameters have a getter, and if the corresponding parameter isNone,
additional information is being fetched from anime's main page.
All parameters are optional, but at least one ofname:Name, id:strmust be specified.Anime.download().download(quality:int|None=None,path:str="",threads:int=1)Downloads the whole anime, walking over seasons and episodes
iteratively and downloading each.qualityparameter specifies
the quality of the videos to be downloaded.
IfqualityisNone, highest quality will be used.threadsparameter with default value1, if it is specified to be not equal1,
will create a ThreadPool and download simultaneously.
Downloading whole anime will create a folder with it's name and subfolders for seasons.
Parameterpathwill add a path in front of the output file and save the file
where specified.Examplequality:720Anime.selector.selector:SelectorProperty of anAnimeobject, helps with selecting specific episodes for download.
See more inSelectorContentContent(seasons:list[Season],films:Season|None=None)Contentobject provides an accessor for theSeasons and films of an anime.
Some animes have no films, therefore sometimes the parameterfilmsisNoneContent.count.count:intThe count property gives the total count of episodes in seasons.SeasonSeason(title:str|None,episodes:list[Episode],name:Name|None=None)ASeasonmay be a normal season or the container for anime's films.
Seasons'titleis the general name of the season, which is mosltySeason <number>orFull-length Filmsfor films container.
State ofnamecan be different in following situations:Anime has only one season: name isNoneAnime has multiple unnamed seasons: name'sidis presentAnime has mutliple named seasons: name is fully presentMore aboutNameobject is written further down.Season.download().download(quality:int|None=None,path:str="",threads:int=1)Pretty much the same asAnime.download().pathis added in front of all locations, so that
the actual downloading happens at that location.
Creates folders if the anime has multiple seasons,
downloads in the final folder directly, if the season is only one.EpisodeEpisode(title:str|None=None,name:Name|None=None,duration:int|None=None,opening:Opening|None=None,ending:Ending|None=None,players:list[Player]|None=None,thumbnail:str|None=None,preview:str|None=None,id:str|None=None)Pretty much the same asAnimeclass.titleis the general name of the episode.
Fetching episode fromAnimeand getting it with
an id fromAPI.anime()will produce different titles.durationis the length of the episode in seconds.previewandthumbnailare links to pictures of
the preview and thumbnail respectively.OpeningandEndingobjects will be explained later.playersproperty is a list ofPlayerobjects,
which also will be explained later.Episode.download().download(quality:int|None=None,path:str="")Downloads an episode with givenquality.
IfqualityisNone, highest quality will be used.pathwill be added to the title and the episode
will be downloaded into the resulting file.Episode.player().player(quality:int|None=None)->Player|NoneGets a player with the givenqualityor
returnsNoneif the player is not found.
IfqualityisNone, returns highest quality player.OpeningOpening(begin:int,end:int,link:str)beginandendare timestamps of the opening.linkis the link to the music provided by the site.EndingEnding(begin:int,link:str)Pretty much the same as theOpeningclass.PlayerPlayer(quality:int|None=None,link:str)Internal object to manage the video of an episode.Player.download().download(local:str|None=None)Downloads the video to a local file with the name
of parameterlocal. If it isNonethen the
file name used on the server will be chosen.FilterFilter(genres:list[Name]=[],types:list[Name]=[],years:list[Name]=[],sorting:list[Name]=[],link:str|None=None)TheFilterobject is used to filter out
results in searching the API, or to describe
an already found anime with it's genres, types,
publishing years etc. In addition to those
lists, a link can be given, which describes the filter.Examplelink:adventure-comedy-game/2000-2007-and-2008-2014/Filter.availableFilter.available:FilterStatic property of the objectFilter, gives
back anotherFilterobject, which has all
the genres, types etc. available on the site.NameName(name:str|None,id:str,orig:str|None=None)TheNameobject is used in various places to name things.
Since the jut.su site is in russian language, thenameis the visible name,origis the english or japanese name
andidis the id used on the site for navigation, fetching etc.SelectorSelector(parent:Anime)A helper object for specific selections of episodes for download.Selector.select_episodes().select_episodes(quality:int|None=None,items:Iterable[int]|None=None)->DownloaderSelects episodes with specific indexes. This ignores seasons and
counts each next episode asindex + 1. Be careful: Index of episodes starts with a0.
IfitemsisNone, everything will be selected.
The selection quality is the parameterquality. If it isNone, highest
quality will be selected.Selector.select_seasons().select_seasons(quality:int|None=None,items:Iterable[int]|None=None)->DownloaderSelects seasons with specific indexes. Those selected seasons are selected
completely including all their episodes. Indexing begins with a0.
IfitemsisNone, everything will be selected.
The selection quality is the parameterquality. If it isNone, highest
quality will be selected.Selector.select_in_seasons().select_in_seasons(quality:int|None=None,items:dict[int,Iterable[int]|None])->DownloaderSelects specific episodes in specific seasons. Seasons index goes into
the key of dictionary, the value is an iterator of indexes inside this episode.
The selection quality is the parameterquality. If it isNone, highest
quality will be selected.DownloaderDownloader(items:list[list[Player,str]])The object being returned fromSelector.Downloader.add().add(downloader:Downloader)Adds items of another downloader to itself. Created for merging queues.Downloader.download().download(path:str="",threads:int=1)Downloads the queue of the object using threads and apath, which is being added
in front of the location.ExampleThe following example will download the anime
"One Punch Man" into weeb's secret anime folder
in full quality and will use 3 threads
to download simultaneously.fromjutsu_apiimportAPIapi=API(verbosity=1)search=api.search(keyword="punch")onepunch=search[0]onepunch.download(path="/home/weeb/homework/",threads=3)This example usesSelectorto download everything after episode 5:fromjutsu_apiimportAPIapi=API(verbosity=1)search=api.search(keyword="punch")onepunch=search[0]episodes=onepunch.selector.select_episodes(range(5,onepunch.content.count))episodes.download(path="/home/weeb/homework/",threads=3)