Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request: respect only torrent file avaliable scenario in anime-torrent-provider #138

Open
2 of 3 tasks
EnergoStalin opened this issue Sep 23, 2024 · 5 comments
Open
2 of 3 tasks
Labels
feature request New feature or request
Milestone

Comments

@EnergoStalin
Copy link

EnergoStalin commented Sep 23, 2024

Checklist

  • I checked that this feature has not been requested before
  • I checked that this feature is not in the "Not planned" list
  • This feature will benefit the majority of users

Problem Description / Use Case

I'm writing extension to support jackett aggregator cause i need authentication/proxy for most trackers to work and turns out some trackers don't use magnets at all for example animelayer

part of jackett aggregated response
http://127.0.0.1:9117/api/v2.0/indexers/all/results?apikey=[REDACTED]&Query=VTuber&Category[]=5070
{
	"1": {
		"FirstSeen": "0001-01-01T00:00:00",
		"Tracker": "AnimeLayer",
		"TrackerId": "animelayer",
		"TrackerType": "semi-private",
		"CategoryDesc": "TV/Anime",
		"BlackholeLink": null,
		"Title": "VTuber Nanda ga Haishin Kiriwasuretara Densetsu ni Natteta / Витубер (12 из 12) Complete [1080p]",
		"Guid": "https://www.animelayer.ru/torrent/668c20076603002d6d4d4009/download/",
		"Link": "http://127.0.0.1:9117/dl/animelayer/?jackett_apikey=[REDACTED]&path=Q2ZESjhLb1ZtQllNaHR0TXRmcXlJUXNDWmRFV2M3U3pxTmRhbkk5ZndHOU9kU2VCMWdWaVlDWC16WkVyOHlCT0FSUXlqcHpsYjJPdFRsamhCT0k0SG9WQnlJOUtqRERndFhhcVZLN3J3akdTOVl0N0wxTzE2RkVhNDdNb3Mtb01PQ2ZZRGpDRC1uM185OFRsa25vSUM1eWgxS2xiMHdjVlNiWi1HMkF5a2ZuV3Uxd3hMUEVvNl9VQWRhMXktUG5qOVB3ZVpHMEdRd1cwREF6QVJSbjVlWnRic1Fj&file=VTuber+Nanda+ga+Haishin+Kiriwasuretara+Densetsu+ni+Natteta+_+%D0%92%D0%B8%D1%82%D1%83%D0%B1%D0%B5%D1%80+(12+%D0%B8%D0%B7+12)+Complete+%5B1080p%5D",
		"Details": "https://www.animelayer.ru/torrent/668c20076603002d6d4d4009/",
		"PublishDate": "2024-09-22T19:26:00",
		"Category": [
			5070,
			128002
		],
		"Size": 4273492480,
		"Files": null,
		"Grabs": null,
		"Description": "Субтитры:  русские (софтсаб) - Язык:  японский",
		"RageID": null,
		"TVDBId": null,
		"Imdb": null,
		"TMDb": null,
		"TVMazeId": null,
		"TraktId": null,
		"DoubanId": null,
		"Genres": null,
		"Languages": [],
		"Subs": [],
		"Year": null,
		"Author": null,
		"BookTitle": null,
		"Publisher": null,
		"Artist": null,
		"Album": null,
		"Label": null,
		"Track": null,
		"Seeders": 16,
		"Peers": 2,
		"Poster": "http://127.0.0.1:9117/img/animelayer/?jackett_apikey=[REDACTED]&path=Q2ZESjhLb1ZtQllNaHR0TXRmcXlJUXNDWmRFRlVyRWN3ZUc5LWxkMFE0NHFHajZaLXE4RjZyQi1zZXRlMFZFUjFUV3hYazBCQnZFZFhRelRLTXd5cDVPdjI4LWxmallOV2FtXzdOX2Z5R2VyVjIzZFdOR0Q1Z05wdHk5Tkhfb3FSMmJZRkhDRkkxQnJwWFk5dXNfM2h6WmlYa1VMWVdiLThyVGlMdUVZQ3ZwR2NfWkxzdUFGVkdjU2xmcW5EeklLdDhFaTV4NVlHLTF2d3RYQW9qZGg0alRTUm9FVUdZd2lGbENjVUc5QWJoYkxfOG5iT0RJdnZ6SUtFbGFjVVd3aUxxQVRScFU1TlFkV2c4MW4zeHZKVFVhd1lINA&file=poster",
		"InfoHash": null,
		"MagnetUri": null,
		"MinimumRatio": null,
		"MinimumSeedTime": null,
		"DownloadVolumeFactor": 0,
		"UploadVolumeFactor": 1,
		"Gain": 63.68000030517578
	}
}

Proposed Solution

Although i can definitely try bundling parse-torrent from webtorrent i want to avoid doing so at all cost since it makes no sense when extension host can perform the conversion.

So any of this would be sufficient in my case

  1. Respect torrent.Link in case magnet is omitted (disregard potential cookie authentication)
  2. Expose torrent file to magnet conversion in api
@EnergoStalin EnergoStalin added the feature request New feature or request label Sep 23, 2024
@EnergoStalin EnergoStalin changed the title feature request: allow supplying exclusively torrent file in extension feature request: respect only torrent file avaliable scenario in anime-torrent-provider Sep 23, 2024
@5rahim
Copy link
Owner

5rahim commented Sep 25, 2024

So, if I'm following correctly, by "Respect torrent.Link in case magnet is omitted" you mean handling the case where only the downloadUrl is provided and not the magnet link. If so, I can add the logic to download it to a temporary folder & sending that to the torrent client. There's no ETA for the next release however.

@5rahim 5rahim added this to the v2.2.0 milestone Sep 25, 2024
@EnergoStalin
Copy link
Author

EnergoStalin commented Sep 25, 2024

Yes but it would disregard potential cookie authentication as I stated already so it might not be perfect solution.

As far as I know animelayer is the only tracker which doesn't provide magnet links at all.

Option 2 is preferable cause someone might need it eventually when implementing direct private tracker extension. I remember that's in not planned list so do as you see fit.

Technically it's still possible to write extension for private tracker it just require messing up with code first which is not hard since it's always plaintext or host settings via http since extensions lack native support for them. I mean jackett API won't work without token either.

@5rahim
Copy link
Owner

5rahim commented Sep 25, 2024

it just require messing up with code first which is not hard since it's always plaintext or host settings via http since extensions lack native support for them.

Yeah, extensions can't store user info for now but for later versions I might add a feature to allow them to ask for config values that will be exposed in the code. To avoid issues though, these configs will be reset after every extension update.

Option 2 is preferable cause someone might need it eventually when implementing direct private tracker extension

I'm not really familiar with how to parse private tracker torrent to magnet links, Seanime also doesn't currently have a built-in way to do that. Also don't know how that would work towards cookie authentication since I guess in both cases the file needs to be downloaded (unless I'm wrong).

@EnergoStalin
Copy link
Author

EnergoStalin commented Sep 25, 2024

I imagine the flow in second case that way:

Extension domain -> On getTorrentMagnetLink called download torrent file(handle cookie there) -> Convert received buffer to base64 for simplicity -> Call provided by seanime convert method -> Seanime domain -> Convert received base64 encoded file to magnet(seems like anacrolix/torrent/metainfo can handle that) -> Extension domain -> Return magnet.

Working conversion example
import (
	"bytes"
	"encoding/base64"
	"fmt"
	"os"

	"github.com/anacrolix/torrent/metainfo"
)

func b64torrent2magnet(base64Torrent string) (string, error) {
	torrentData, err := base64.StdEncoding.DecodeString(base64Torrent)
	if err != nil {
		return "", err
	}

	torrentDataReader := bytes.NewReader(torrentData)
	meta, err := metainfo.Load(torrentDataReader)
	if err != nil {
		return "", err
	}

	magnetLink, err := meta.MagnetV2()
	if err != nil {
		return "", err
	}

	return magnetLink.String(), nil
}

func main() {
	content, _ := os.ReadFile("b64torrent.txt")

	fmt.Println(b64torrent2magnet(string(content)))
}
Extension site example
class Provider {
  async getTorrentMagnetLink(torrent: AnimeTorrent): Promise<string> {
	if(torrent.magnetLink) {
		return torrent.magnetLink
	}

	if(!!torrent.downloadUrl) {
		return ""
	}

	// Should be binary but i don't see blob in response definition this might break torrent
	const data = await fetch(torrent.downloadUrl).then(e => e.text())

	// Kinda try to restore original buffer
	const buffer = CryptoJS.enc.Utf8.parse(data)
	const b64 = CryptoJS.enc.Base64.stringify(buffer)

    return b64torrent2magnet(b64) // globall call
  }
}

Base64 is optional cause i'm myself not sure how to pass raw buffers across host and extension. If you know the way please avoid base64.

There's another option i was thinking of is to directly accept base64 encoded torrent file in getTorrentMagnetLink callback but it's kinda counter intuitive and ambiguous.

@5rahim
Copy link
Owner

5rahim commented Sep 28, 2024

Managed to make it work, so something like this will be possible

async getTorrentMagnetLink(torrent: AnimeTorrent): Promise<string> {
    if(torrent.magnetLink) return torrent.magnetLink
    if(!torrent.downloadUrl) return ""

    const data = await (await fetch(torrent.downloadUrl)).text()
    return getMagnetLinkFromTorrentData(data)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request
Projects
Status: Review
Development

No branches or pull requests

2 participants