\/\fR
65 | Specify the title to use for ani-skip
66 | .PP
67 | .SH
68 | ENVIRONMENT VARIABLES
69 | .PP
70 | ani-cli v4 uses environment variables to control unstable/untested and niche features in addition to everything that has an option. Command-line options take precedence over env vars. Note that these are all subject to change.
71 | .TP
72 | \fBANI_CLI_MODE\fR
73 | Controls the scraped media's mode, valid options are sub or dub. Default is sub.
74 | .TP
75 | \fBANI_CLI_DOWNLOAD_DIR\fR
76 | Controls the directory where files are downloaded. Default is the current dir.
77 | .TP
78 | \fBANI_CLI_QUALITY\fR
79 | Controls the scraped media's quality, check allanime for valid options or set to worst/best. Default is best.
80 | .TP
81 | \fBANI_CLI_PLAYER\fR
82 | Sets the player ani-cli uses. Can be debug (print links), download (equivalent to -d), android_mpv (apk and am start), android_vlc (apk and am start), flatpak_mpv (for flatpak), catt (for streaming to tv), or any player that can play urls. For defaults see working without arguments.
83 | .TP
84 | \fBANI_CLI_EXTERNAL_MENU\fR
85 | Controls the frontend of ani-cli. Can be 0 (uses fzf) or 1 (uses rofi dmenu). Default is 0.
86 | .TP
87 | \fBANI_CLI_MULTI_SELECTION\fR
88 | Controls the multi flag for the chosen frontend. Default is -m for fzf and --multi-select for rofi dmenu.
89 | .TP
90 | \fBANI_CLI_NON_INTERACTIVE\fR
91 | Enabled by default if both -e and -S are given. Disables fzf dependency check. Also disables some debug information if running with ANI_CLI_PLAYER="debug"
92 | .TP
93 | \fBANI_CLI_HIST_DIR\fR
94 | Controls the directory ani-cli uses for storing history. A /ani-cli subfolder is created there for the histfile if doesn't exists. Default is $XDG_STATE_HOME if set, $HOME/.local/state if not.
95 | .TP
96 | \fBANI_CLI_DEFAULT_SOURCE\fR
97 | Controls the default source. Valid is history (equivalent to -c), everything else means search. Default is search.
98 | .TP
99 | \fBANI_CLI_SKIP_INTRO\fR
100 | Controls if ani-skip is used to skip intros (works with mpv only). Can be 0 (disabled) or 1 (enabled). Default is 0.
101 | .TP
102 | \fBANI_CLI_NO_DETACH\fR
103 | Controls if mpv is detached from the main process for playback, which can be useful for use with terminal renderers such as kitty. (works with mpv only). Can be 0 (disabled) or 1 (enabled). Default is 0.
104 | .TP
105 | \fBANI_CLI_SKIP_TITLE\fR
106 | Overrides the anime title to query for skip times. Can be any string value. Default is empty, resolving to the anime title as given by ani-cli.
107 | .PP
108 | .SH EPISODE SELECTION
109 | .PP
110 | Multiple episodes can be chosen using fzf (or alternative frontend's) multi-selection mode. For this refer to their instructions.
111 | .SH BUGS
112 | .PP
113 | Use the GitHub issue tracker:
114 | https://github.com/pystardust/ani-cli/issues
115 | .SH COPYRIGHT
116 | .PP
117 | ani-cli is licensed under the GNU General Public License v3.0
118 | .PP
119 | This program is free software: you can redistribute it and/or modify
120 | it under the terms of the GNU General Public License as published by
121 | the Free Software Foundation, either version 3 of the License, or
122 | (at your option) any later version.
123 | .PP
124 | This program is distributed in the hope that it will be useful,
125 | but WITHOUT ANY WARRANTY; without even the implied warranty of
126 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
127 | GNU General Public License for more details.
128 | .PP
129 | You should have received a copy of the GNU General Public License
130 | along with this program. If not, see .
131 |
--------------------------------------------------------------------------------
/disclaimer.md:
--------------------------------------------------------------------------------
1 |
2 | Disclaimer
3 |
4 |
5 |
6 |
This project: ani-cli
7 |
8 |
9 |
10 | The core aim of this project is to co-relate automation and efficiency to extract what is provided to a user on the internet. All content available through the project is hosted by external non-affiliated sources.
11 |
12 |
13 |
14 | Any content served through this project is publicly accessible. If your site is listed in this project, the code is pretty much public. Take necessary measures to counter the exploits used to extract content in your site.
15 |
16 | Think of this project as your normal browser, but a bit more straight-forward and specific. While an average browser makes hundreds of requests to get everything from a site, this project goes on to make requests associated with only getting the content served by the sites.
17 |
18 |
19 |
20 | This project is to be used at the user's own risk, based on their government and laws.
21 |
22 | This project has no control on the content it is serving, using copyrighted content from the providers is not going to be accounted for by the developer. It is the user's own risk.
23 |
24 |
25 |
26 |
27 |
28 | DMCA and Copyright Infrigements
29 |
30 |
31 |
32 |
33 | A browser is a tool, and the maliciousness of the tool is directly based on the user.
34 |
35 |
36 | This project uses client-side content access mechanisms. Hence, the copyright infrigements or DMCA in this project's regards are to be forwarded to the associated site by the associated notifier of any such claims. As of writing this is [allanime](https://allanime.to)
37 |
38 | Do not harass the maintainer.
39 |
40 |
41 | Contacting the maintainer
42 |
43 |
44 |
45 | Begin by making a GitHub issue or sending an email to port19@port19.xyz
46 |
47 |
--------------------------------------------------------------------------------
/hacking.md:
--------------------------------------------------------------------------------
1 | # Hacking ani-cli
2 | Ani-cli is set up to scrape one platform - currently allanime. Supporting multiple sources at a time would require more changes than we (the maintainers) find worth doing, for this reason any feature request asking for a new site is rejected.
3 |
4 | However ani-cli being open-source and the pirate anime streaming sites being so similar you can hack ani-cli to support any site that follows a few conventions.
5 |
6 | ## Prequisites
7 | Here's the of skills you'll need and the guide will take for granted:
8 | - basic shell scripting
9 | - understanding of http(s) requests and proficiency with curl
10 | - ability to read html and javascript on a basic level and search them
11 | - writing regexes
12 | You'll also need web browser with a debugger and environment that can run unmodified ani-cli
13 |
14 | ## The scraping process
15 | The following flowchart demonstrates how ani-cli operates from a scraping standpoint:
16 |
17 | 
18 |
19 | The steps to get to a link from a query is the following:
20 | 1. search with the site's search page for the query
21 | 2. extract IDs from response, user chooses one
22 | 3. extract episode numbers from an overview page, user chooses one
23 | 4. download player(s) for that id+episode number combination, extract links
24 | 5. quality selection selects one that is played
25 | From here 1-4 need to be changed to support another site. #Reverse-engineering will answer how.
26 |
27 | ## Reverse-engineering
28 | Many sites have various protections against reverse-engineering.
29 | The extension webapi-blocker can help you with bringing up the debugger that we'll use during this guide or to conceal the presence of a debugger.
30 | These reverse-engineering protections are always evolving though so there's no silver bullet - you'll have to do your own research on how to get around them.
31 |
32 | An adblocker can help with reducing traffic from the site, but beware of extensions that change the appearance of the site (eg. darkreader) because they can alter the html/css.
33 |
34 | Once you have the pages (urls) that you're interested in, it's easier to inspect them from less/an editor.
35 | The debugger's inspector can help you with finding what's what but finding patterns/urls is much easier in an editor.
36 | Additionally the debugger doesn't always show you the html faithfully - I've experineced some escape sequences being rendered, capitalization changing - so be sure you see the response of the servers in raw format before you write your regexes.
37 |
38 | ### Core concepts
39 | If you navigate the site normally from the browser, you'll see that each anime is represented with an URL that compromises from an ID (that identifies a series/season of series) and an episode number.
40 | The series identifier is stored in the `id` variable by the script and the episode number in the `ep_no` number.
41 |
42 | Each episode has an embedded player that contains the links to the videos to be played.
43 | Your goal is to get these links along with the resolution (quality) of the streams.
44 | The embedded player has a separate URL from the episode page, but you can always get there from the episode page (and in some cases just by knowing the id and the episode number).
45 |
46 | ### Searching
47 | The search page is usually easy to find on these websites. The searching method varies.
48 | Some sites will have you post a database query in plaintext, some just use a get request with a single variable.
49 | Just try searching for a few series and see how the URL changes (most of the times the sites use a get request for this purpose).
50 | If the site uses a POST request or a more roundabout way, use the debugger to analyze the traffic.
51 |
52 | Once you figured out how searching works, you'll have to replicate it in the `search_anime` function.
53 | The `curl` in this function is responsible for the search request, and the following `sed` regexes mold the respons into many lines of `id\ttitle` format.
54 | The reason for this is the `nth` function, see it for more details.
55 | You'll have to change some variables in the process (eg. allanime_base) too.
56 |
57 | If you have done everything correctly, you can run `ani-cli`, query your site of choice and select from the responses.
58 | Then ani-cli should fail without a message.
59 | If it fails with `No results found!` you have debugging to do.
60 | Running ani-cli with `sh -x` is a good way to debug.
61 |
62 | ### Episode selection
63 | Having completed the previous step, the `id` and `title` will contain the selected title and the corresponding id.
64 |
65 | Now you'll have to look at the page where all the episodes of the series are listed.
66 | This might be a series overview page (like with allanime) or there might not be such, but the episode pages have links to all episodes.
67 |
68 | You'll have to edit the `episodes_list` function that downloads this list of urls.
69 | You need to rewrite the web request and the following regexes to achieve a list of episode numbers separated by newlines and preferably sorted.
70 | Again the `nth` function is used to offer a selection.
71 |
72 | If you have done everything correctly, now you can search for a title, get its episodes listed and select an episode.
73 | Then ani-cli should fail with `Episode not released!`
74 |
75 | ### Getting the player embed
76 | After selecting an episode, the next step is to load its page and extract the embed(s).
77 | In case you can get them without loading the episode page, replace from the `get the embed urls...` part of the code to the removal of the cache dir with a single call to `get_links` and load its output into `links`.
78 | Then move to the next step (and remove all functions rendered unused).
79 |
80 | The first request is to get the episode page, then the following commands extract the embed players' links, one at a line with the format `sourcename : url`.
81 | These are listed into `resp`.
82 | From here they are separated and parsed by `provider_init` and the first half onf `generate_link`.
83 | Some sites (like allanime) have these urls not in plaintext but "encrypted". The decrypt allanime function does this post-processing, it might need to be changed or discarded completely.
84 |
85 | If there's only one embed source, the `generate links..` block can be reduced to a single call to `generate_link`.
86 | The current structure does the agregation of many providers asynchronously, but this is not needed if there's only one source.
87 |
88 | ### Extracting the media links
89 |
90 | Once you have the embed player, it needs to be parsed for the media link.
91 | This is done in the script with the `get_links` function.
92 |
93 | Here first the embed player is first requested and loaded into `episode_link` the media links are extracted.
94 | They need to be printed to the function's stdout in a format of `quality >link`.
95 | The quality string needs to be extracted from the player along with the link and is supposed to be a numeric representation of the resolution.
96 | Sometimes a resolution can't be determined, in this case have the regex match for whatever is in its place.
97 |
98 | The output of the `get_links` function needs to be concatenated into the `links` variable - with a single call if there's only one source, or with the asynchronous mode if there are more.
99 | From here the `get_episode_url` function will continue with quality selection which you need not to alter.
100 |
101 | ## Other functionality
102 | Assuming you completed all the necessary modifications, ani-cli should completely work for you now.
103 | The UI and the history system works as long as you keep the structure of the original code and the format of the responses.
104 |
105 | There might be cases that can't be covered by the current structure of ani-cli, but still it works for most sites as I've observed.
106 |
107 | ## UX Spec
108 |
109 | There also exists a UX spec if you want to replicate the ani-cli user experience in a fresh codebase:
110 | 
111 |
--------------------------------------------------------------------------------
/matrix.md:
--------------------------------------------------------------------------------
1 | To get invited to ani-cli matrix space send an email to `8klv0leh7 at mozmail.com` with the following contents:
2 | ```
3 | Subject: ani-cli matrix space invite
4 | Body: @yourusername:matrixserver
5 | ```
6 |
7 | It might take some time before you get invited.
8 |
--------------------------------------------------------------------------------
/shell.nix:
--------------------------------------------------------------------------------
1 | {
2 | pkgs ? import {},
3 | withMpv ? true,
4 | withVlc ? false,
5 | withIina ? false,
6 | chromecastSupport ? false,
7 | syncSupport ? false
8 | }:
9 |
10 | # To start the dev shell use the comment nix-shell
11 | # use --arg withVlc true to use VLC
12 | # use --arg withIina true to use Iina
13 | # use --arg chromecastSupport true to use chromecastSupport
14 | # use --arg syncSupport true to use syncSupport
15 |
16 | assert withMpv || withVlc || withIina;
17 |
18 | with pkgs;
19 | mkShell {
20 | name = "ani-cli dev shell";
21 | buildInputs = [ shfmt shellcheck (ani-cli.override ({ withMpv = withMpv; withVlc = withVlc; withIina = withIina; chromecastSupport = chromecastSupport; syncSupport = syncSupport; })).runtimeDependencies ];
22 | }
23 |
--------------------------------------------------------------------------------