Skip to content
This repository has been archived by the owner on Aug 30, 2022. It is now read-only.

Latest commit

 

History

History
163 lines (109 loc) · 7.6 KB

CONTRIBUTING.MD

File metadata and controls

163 lines (109 loc) · 7.6 KB

Contributing

Prerequisites

Before you start, please note that you should be able to use the following technologies. Existing contributors will not actively teach them to you.

  • Basic Android developement
  • Java
  • Web Scraping
    • HTML
    • JavaScript*
    • JSoup*

* maybe not required depending on your implementation

Tools

  • Android Studio
  • Emulator or phone ready for development and Tenshi installed
  • Google Chrome on the host machine (useful when debugging Web Adapters)

Getting Help

Theres currently no discord or anything setup, so please refer to existing Content Adapters for examples.
If required, you can also write a issue

Writing a Content Adapter

Content Adapters are a way to provide content, like episode streams, to Tenshi.
Adapters are implemented as Android Services with a AIDL interface.

There are two ways of writing a Content Adapter:

Web Adapters

A Web Adapter is essentially just a WebView with Javascript injected into the page.
A Web Adapter consists of a json definition and a payload that is injected into the page.

To start developing a Web Adapter, clone this repository and set DEBUG_MODE to true.

Definition

The definition of a Web Adapter is loaded every time the WebAdapterService is initialized.
When in debug mode, write your definition in the file in raw/debug_definition.json.

Format

[
  {
    "name": "fouranime.web",
    "displayName": "4Anime",
    "storagePattern": null,
    "searchUrl": "https://4anime.to/?s=%s",
    "episodeUrl": "https://4anime.to/%s-episode-%02d",
    "payload": "webadapters/payloads/4anime.json",
    "userAgentOverride": null,
    "domStorageEnabled": null,
    "allowContentAccess": null
  }
]
Property Description
name a unique name for your adapter
displayName the name shown to the user
storagePattern a regex pattern to validate the persistent storage. null to disable
searchUrl search url used when persistent storage is empty. %s is replaced with the name of the anime, url- escaped
episodeUrl url to directly go to a episode. %s is replaced with the contents of persistent storage, %d with the episode number
payload javascript payload of this adapter, relative to PAYLOAD_ROOT
userAgentOverride controls the user agent of the webview. left default if null
domStorageEnabled controls dom storage. left default if null
allowContentAccess controls content access. left default if null

Payload

The payload of a Web Adapter is loaded every time it is injected into the page.
When in debug mode, write your definition in the file in raw/debug_payload.js.

Writing the payload is, of course, highly dependent on the page you are writing it for.
See webadapter/payloads for examples.

The general goals:

  • write something to persistent storage that, in combination with the episodeUrl of the definition, gets the user to the episode page as direct as possible
  • get the video url from the page
  • block (disruptive) ads

Javascript interface

The following functions are accessible to Payloads:

App. Description
toast(String) make a toast
log(String) write a message to Log.d, tag "JSInterface"
logE(String) write a message to Log.e, tag "JSInterface"

* see JSInterface

Tenshi. Description
getUniqueName() the current unique name
getAnimeTitle() the (english) anime title
getAnimeTitleJp() the (japanese) anime title
getMalId() the MAL id of the anime
getPersistentStorage() get the contents of persistent storage
setPersistentStorage(String) set the contents of persistent storage
finish(String) closes the webview and forwards the argument as stream url to Tenshi

* see WebAdapterJs

Debugging

When running a debug build with DEBUG_MODE enabled, the WebAdapterActivity will enable Web Contents Debugging, allowing you to (kinda) open full Chrome DevTools on your webview by opening chrome://inspect on your host PC with the phone or emulator connected to it.

Quick Note: Chrome is (at least for me) sometimes very slow to connect to the webview. So bring patience when debugging.

Native Adapters

A native adapter gives you more control over how things work, and also allows you to create a adapter without a ui (or a custom one).

The most barebone Content Adapter just extends Service and returns a implementation of IContentAdapter.Stub in onBind().

If you need a activity for your adapter, you can use a ActivityAdapterService.

After writing your Content Adapter Service, you have to add it to your manifest like so:

<service
    android:name=".webadapter.WebAdapterService"
    android:exported="true">

    <intent-filter>
        <action android:name="io.github.shadow578.tenshi.content.ADAPTER" />
        <category android:name="io.github.shadow578.tenshi.content.ADAPTER" />
    </intent-filter>

    <meta-data
        android:name="io.github.shadow578.tenshi.content.ADAPTER_VERSION"
        android:value="2" />
</service>

the service must:

  • be exported (android:exported="true")
  • define a intent filter with action and category set to "io.github.shadow578.tenshi.content.ADAPTER"
  • contain meta-data "io.github.shadow578.tenshi.content.ADAPTER_VERSION" with value set to the same value as in the used extension lib (see IContentAdapter or Constants).

Debugging

Debugging of Content Adapters is easiest done using the TestActivity. This uses the same logic to bind the adapters and allows for you to set breakpoints.