[CI SKIP] Some CONTRIBUTING.md cleanup

This commit is contained in:
arkon 2020-06-09 18:12:38 -04:00
parent 885138d9ed
commit 6ab30f8e2c
1 changed files with 53 additions and 34 deletions

View File

@ -89,54 +89,73 @@ dependencies {
} }
``` ```
(Note that Gson, and several other dependencies, are already exposed to all extensions via `common.gradle`.)
Notice that we're using `compileOnly` instead of `implementation`, since the app already contains it. You could use `implementation` instead for a new dependency, or you prefer not to rely on whatever the main app has at the expense of app size. Notice that we're using `compileOnly` instead of `implementation`, since the app already contains it. You could use `implementation` instead for a new dependency, or you prefer not to rely on whatever the main app has at the expense of app size.
Note that using `compileOnly` restricts you to versions that must be compatible with those used in Tachiyomi v0.8.5+ for proper backwards compatibility. Note that using `compileOnly` restricts you to versions that must be compatible with those used in Tachiyomi v0.8.5+ for proper backwards compatibility.
### Extension call flow ### Extension call flow
- **Extension Main Class** #### Main class
- The extension Main class which is refrenced and defined by `extClass`(inside `build.gradle`) should be inherited from either `SourceFactory` or one of `Source` children: `HttpSource` or `ParsedHttpSource`.
- `SourceFactory` is used to expose multiple `Source`s, only use it when there's **minor difference** between your target sources or they are essentially mirrors to the same website. The class which is refrenced and defined by `extClass` in `build.gradle`.
- `HttpSource` as in it's name is for a online http(s) source, but `ParsedHttpSource` has a good model of work which makes writing scrapers for normal aggregator websites much easier and streamlined. (again, you can find the implementation of the stubs in the app as mentioned above)
- The app starts by finding your extension and reads these variables: This class should implement either `SourceFactory` or one of the `Source` implementations: `HttpSource` or `ParsedHttpSource`.
- `SourceFactory`: used to expose multiple `Source`s. Use it when there's minor differences between your target sources or they are essentially mirrors to the same website.
- `HttpSource`: for online source, where requests are made using HTTP.
- `ParsedHttpSource`: similar to `HttpSource`, but has methods useful for scraping pages.
Key variables:
| Field | Description | | Field | Description |
| ----- | ----------- | | ----- | ----------- |
| `name` | Name to your target source as displayed in the `sources` tab inside the app | | `name` | Name displayed in the "Sources" tab in Tachiyomi. |
| `id` | identifier of your source, automatically set from `HttpSource`. It should only be manually set if you need to copy an existing autogenerated ID. | | `baseUrl` | Base URL of the source without any trailing slashes. |
| `supportsLatest` | if `true` the app adds a `latest` button to your extension | | `lang` | An ISO 639-1 compliant language code (two letters in lower case). |
| `baseUrl` | base URL of the target source without any trailing slashes | | `id` | Identifier of your source, automatically set in `HttpSource`. It should only be manually overriden if you need to copy an existing autogenerated ID. |
| `lang` | as the documentation says "An ISO 639-1 compliant language code (two letters in lower case).", it will be used to catalog your extension |
- **Popular Manga** #### Popular Manga
- When user presses on the source name or the `Browse` button on the sources tab, the app calls `fetchPopularManga` with `page=1`, and it returns a `MangasPage` and will continue to call it for next pages, when the user scrolls the manga list and more results must be fetched(until you pass `MangasPage.hasNextPage` as `false` which marks the end of the found manga list)
- While passing magnas here you should at least set `url`, `title` and *`thumbnail_url`; `url` must be unique since it's used to index mangas in the DataBase.(this information will be cached and you will have a chance to update them when `fetchMangaDetails` is called later). a.k.a. the "Browse" source entry point in the app.
- You may not set `thumbnail_url`, which will make the app call `fetchMangaDetails` over every single manga to show the cover, so it's better to set the thumbnail cover in `fetchPopularManga` if possible. The same is true with latest and search.
- **Latest Manga** - The app calls `fetchPopularManga` with `page=1`, and it returns a `MangasPage` and will continue to call it for next pages, when the user scrolls the manga list and more results must be fetched (until you pass `MangasPage.hasNextPage` as `false` which marks the end of the found manga list).
- If `supportsLatest` is set to true the app shows a `Latest` button in front for your extension `name` and when the user taps on it, the app will call `fetchLatestUpdates` and the rest of the flow is similar to what happens with `fetchPopularManga`. - While passing magnas here you should at least set `url`, `title` and `thumbnail_url`.
- If `supportsLatest` is set to false no `Latest` button will be shown and `fetchLatestUpdates` and subsequent methods will never be called. - If `thumbnail_url` is not set, `fetchMangaDetails` will be called.
- **Manga Search**
- `getFilterList` will be called to get all filters and filter types. **TODO: explain more about `Filter`** #### Latest Manga
- when the user searches inside the app, `fetchSearchManga` will be called and the rest of the flow is similar to what happens with `fetchPopularManga`.
- **Manga Details** a.k.a. the "Latest" source entry point in the app.
- When user taps on a manga and opens it's information Activity `fetchMangaDetails` and `fetchChapterList` will be called the resulting information will be cached.
- `fetchMangaDetails` is called to update a manga's details from when it vas initialized earlier(you may want to parse a manga details page here and fill the rest of the fields) - Used if `supportsLatest` is `true` for a source
- Note: During a backup, only `url` and `title` are stored, and to restore the rest of the manga data the app calls `fetchMangaDetails`. so you need to fill the rest of the fields, specially `thumbnail_url`. - Similar to popular manga, but should be fetching the latest items from a source.
- `fetchChapterList` is called to display the chapter list, you want to return a reversed list here(last chapter, first index in the list)
- **Chapter** #### Manga Search
- After a chapter list for the manga is fetched, `prepareNewChapter` will be called, after that the chapter will be saved in the app's DataBase and later if the chapter list changes the app will loose any references to the chapter(but chapter files will still be in the device storage)
- **Chapter Pages** - `getFilterList` will be called to get all filters and filter types. **TODO: explain more about `Filter`**
- When user opens a chapter, `fetchPageList` will be called and it will return a list of `Page` - When the user searches inside the app, `fetchSearchManga` will be called and the rest of the flow is similar to what happens with `fetchPopularManga`.
- While a chapter is open the reader will call `fetchImageUrl` to get URLs for each page of the manga
#### Manga Details
- When user taps on a manga, `fetchMangaDetails` and `fetchChapterList` will be called and the results will be cached.
- `fetchMangaDetails` is called to update a manga's details from when it was initialized earlier
- Note: During a backup, only `url` and `title` are stored, and to restore the rest of the manga data the app calls `fetchMangaDetails`, so all fields should be filled in if possible.
- `fetchChapterList` is called to display the chapter list. This should be sorted descending by date.
#### Chapter
- After a chapter list for the manga is fetched, `prepareNewChapter` will be called.
#### Chapter Pages
- When user opens a chapter, `fetchPageList` will be called and it will return a list of `Page`s.
- While a chapter is open the reader will call `fetchImageUrl` to get URLs for each page of the manga.
### Misc notes ### Misc notes
- Some time while you are writing code, you may find no use for some inherited methods, if so just override them and throw exceptions: `throw Exception("Not used")` - Sometimes you may find no use for some inherited methods. If so just override them and throw exceptions: `throw Exception("Not used")`
- You probably will find `getUrlWithoutDomain` useful when parsing the target source URLs. - You probably will find `getUrlWithoutDomain` useful when parsing the target source URLs.
- If possible try to stick to the general workflow from`ParsedHttpSource` and `HttpSource`, breaking them may cause you more headache than necessary. - If possible try to stick to the general workflow from `HttpSource`/`ParsedHttpSource`; breaking them may cause you more headache than necessary.
- When reading the code documentation it helps to follow the subsequent called methods in the the default implementation from the `app`, while trying to grasp the general workflow.
## Running ## Running