Skip to content

Commit

Permalink
Updated fvp version and added 2 portuguese anime sources
Browse files Browse the repository at this point in the history
  • Loading branch information
K3vinb5 committed Jun 18, 2024
1 parent 8bfd7f6 commit da86fc5
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 10 deletions.
3 changes: 3 additions & 0 deletions lib/screens/anime_details_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class _AnimeDetailsScreenState extends State<AnimeDetailsScreen> {
animeSources = {
0: GogoAnimeSource(),
1: ZoroSource(),
2: GoyabuSource(),
3: AnimesOnlineSource(),
};
updateSource(0);
setUserAnimeModel();
Expand Down Expand Up @@ -291,6 +293,7 @@ class _AnimeDetailsScreenState extends State<AnimeDetailsScreen> {
videoScreen = VideoScreen(
stream: streamAndCaptions[0] ?? "",
captions: streamAndCaptions[1],
referer: streamAndCaptions.length > 2 ? streamAndCaptions[2] : null,
updateEntry: () {
updateEntry(animeEpisode);
},
Expand Down
1 change: 1 addition & 0 deletions lib/screens/manga_details_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ class _MangaDetailsScreenState extends State<MangaDetailsScreen> {
MaterialPageRoute(
builder: (context) => ReadingScreen(
chapterId: chapterId,
getMangaChapterPages: mangaSources[currentSource]!.getMangaChapterPages,
),
),
);
Expand Down
6 changes: 3 additions & 3 deletions lib/screens/reading_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:collection/collection.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:unyo/api/consumet_api.dart';
import 'package:unyo/widgets/widgets.dart';

class ReadingScreen extends StatefulWidget {
const ReadingScreen({super.key, required this.chapterId});
const ReadingScreen({super.key, required this.chapterId, required this.getMangaChapterPages});

final String chapterId;
final Future<List<String>> Function(String) getMangaChapterPages;

@override
State<ReadingScreen> createState() => _ReadingScreenState();
Expand All @@ -32,7 +32,7 @@ class _ReadingScreenState extends State<ReadingScreen> {
}

void initPages() async {
chapterPages = await getMangaMangaHereChapterPages(widget.chapterId);
chapterPages = await widget.getMangaChapterPages(widget.chapterId);
setState(() {
totalPages = chapterPages.length;
//kinda scuffed
Expand Down
14 changes: 14 additions & 0 deletions lib/screens/video_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ class VideoScreen extends StatefulWidget {
required this.stream,
required this.updateEntry,
this.captions,
this.referer,
required this.title,
});

final String stream;
final String? captions;
final String? referer;
final void Function() updateEntry;
final String title;

Expand Down Expand Up @@ -60,6 +62,7 @@ class _VideoScreenState extends State<VideoScreen> {
super.initState();
_controller = VideoPlayerController.networkUrl(
Uri.parse(widget.stream),
httpHeaders: widget.referer != null ? {"Referer": widget.referer!} : {},
closedCaptionFile:
widget.captions != null ? loadCaptions(widget.captions!) : null,
videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),
Expand All @@ -68,6 +71,17 @@ class _VideoScreenState extends State<VideoScreen> {
setState(() {});
});
_controller.setLooping(true);
// temp();
_controller.initialize().then((_) => setState(() {}));
_controller.play();
_resetHideControlsTimer();
interactScreen(true);
_screenFocusNode.requestFocus();
setClientMqttConnection(false);
}

void temp() async {
await Future.delayed(const Duration(seconds: 10));
_controller.initialize().then((_) => setState(() {}));
_controller.play();
_resetHideControlsTimer();
Expand Down
135 changes: 135 additions & 0 deletions lib/sources/anime/animes_online_source.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import 'dart:convert';
import 'package:html/parser.dart' show parse;
import 'package:unyo/sources/anime/anime_source.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class AnimesOnlineSource implements AnimeSource {
@override
Future<List<String?>> getAnimeStreamAndCaptions(
String id, int episode, BuildContext context) async {
final String animePageEndpoint =
"${id.replaceFirst("/anime/", "/episodio/")}-episodio-${episode > 9 ? episode : "0$episode"}";

var url = Uri.parse(animePageEndpoint);
var response = await http
.get(url, headers: {"Referer": "https://animesonline.cloud/"});

final String dataId = getDataId(response, animePageEndpoint);
print("Id -> $dataId");
String animeStreamEndpoint =
"https://animesonline.cloud/wp-json/dooplayer/v2/$dataId/tv/1";

url = Uri.parse(animeStreamEndpoint);
response = await http
.get(url, headers: {"Referer": "https://animesonline.cloud/"});

Map<String, dynamic> jsonResponse = json.decode(response.body);
late String mp4Endpoint;

try {
mp4Endpoint = jsonResponse["embed_url"];
} catch (e) {
print("Json: $jsonResponse \n Id: $dataId");
mp4Endpoint = "";
}

if (!mp4Endpoint.contains("mangas.cloud")) {
animeStreamEndpoint =
"https://animesonline.cloud/wp-json/dooplayer/v2/$dataId/tv/2";

url = Uri.parse(animeStreamEndpoint);
response = await http
.get(url, headers: {"Referer": "https://animesonline.cloud/"});

jsonResponse = json.decode(response.body);
try {
mp4Endpoint = jsonResponse["embed_url"];
} catch (e) {
mp4Endpoint = "";
}
if (!mp4Endpoint.contains("mangas.cloud")) {
animeStreamEndpoint =
"https://animesonline.cloud/wp-json/dooplayer/v2/$dataId/tv/3";

url = Uri.parse(animeStreamEndpoint);
response = await http
.get(url, headers: {"Referer": "https://animesonline.cloud/"});

jsonResponse = json.decode(response.body);
try {
mp4Endpoint = jsonResponse["embed_url"];
} catch (e) {
return [];
}
}
}

mp4Endpoint = mp4Endpoint.replaceFirst(
"https://animesonline.cloud/jwplayer?source=", "");
mp4Endpoint = mp4Endpoint.replaceFirst("&id=$dataId&type=mp4", "");
mp4Endpoint = Uri.decodeFull(mp4Endpoint);
return [mp4Endpoint, null];
}

@override
Future<List<List<String>>> getAnimeTitlesAndIds(String query) async {
//TODO search the html for the ids instead of assuming them
final String titlesAndIdsEndPoint =
"https://animesonline.cloud/wp-json/dooplay/search/?keyword=$query&nonce=2cf7e710c5";
var url = Uri.parse(titlesAndIdsEndPoint);
var response = await http
.get(url, headers: {"Referer": "https://animesonline.cloud/"});
if (response.statusCode != 200) {
//TODO Dialog

// print(response.body);
return [];
}

List<List<String>> titlesAndIds = [[], []];
Map<String, dynamic> jsonResponse = json.decode(response.body);
List<MapEntry<String, dynamic>> entries = jsonResponse.entries.toList();
try {
for (int i = 0; i < entries.length; i++) {
//ids
titlesAndIds[1].add(entries[i].value["url"].toString());
//titles
titlesAndIds[0].add(entries[i].value["title"].toString());
}
} catch (e) {
return [[], []];
}

return titlesAndIds;
}

@override
String getSourceName() {
return "Animes Online (Pt-Br)";
}

String getDataId(http.Response response, String url) {
String htmlContent = response.body;

var document = parse(htmlContent);
var elements = document.querySelectorAll('a[data-id]');

for (var element in elements) {
if (element.attributes['data-id'] == null) continue;
return element.attributes['data-id']!;
}
//If something goes wrong
int startIndex = htmlContent.indexOf('data-id="');
print("startIndex->$startIndex");
if (startIndex != -1) {
startIndex += 'data-id="'.length;
int endIndex = htmlContent.indexOf('"', startIndex);
return "$startIndex-$endIndex";
} else {
print(url);
}

return "error";
}
}
120 changes: 120 additions & 0 deletions lib/sources/anime/goyabu.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import 'package:html/parser.dart';
import 'package:unyo/sources/sources.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';

class GoyabuSource implements AnimeSource {
@override
Future<List<String?>> getAnimeStreamAndCaptions(
String id, int episode, BuildContext context) async {
var url = Uri.parse(id);
var response =
await http.get(url, headers: {"Referer": "https://www.goyabu.us/"});

if (response.statusCode != 200) {
return [];
}

List<String> episodePages = [];
String htmlContent = response.body;
var document = parse(htmlContent);
var elements = document.querySelectorAll('.ultimosEpisodiosHomeItem');
for (var element in elements) {
//episodePages
String? episodePage = element.querySelector('a')?.attributes['href'];
if (episodePage != null) {
episodePages.add(episodePage);
}
}

if (episodePages.length < episode) {
//TODO handle cases where episode is higher than 30
return [];
}

url = Uri.parse("https://www.goyabu.us/${episodePages[episode - 1]}");
// print(episodePages);
response =
await http.get(url, headers: {"Referer": "https://www.goaybu.us/"});

if (response.statusCode != 200) {
return [];
}

htmlContent = response.body;
List<String> lines = htmlContent.split('\n');
List<String> linesWithFile =
lines.where((line) => line.contains('file: ')).toList();
List<String> cleanLines = [];
for (var line in linesWithFile) {
String newLine = line
.replaceAll("\t", "")
.replaceAll("\n", "")
.replaceAll(" ", "")
.replaceAll("file:", "")
.replaceAll("'", "")
.replaceAll(",", "");
newLine = newLine.substring(0, newLine.length - 1);
cleanLines.add(newLine);
}
List<String> qualities = [
"appfullhd",
"apphd",
"apphd2",
/* "appfullhd", */
"apphd2",
"appsd2",
"apphd",
"appsd"
];
for (String quality in qualities) {
for (String line in cleanLines) {
if (line.contains(quality)) {
return [
line /* "https://cdn8.anicdn.net/apphd/43606.mp4" */,
null,
"https://www.goyabu.us/"
];
}
}
}
return [];
}

@override
Future<List<List<String>>> getAnimeTitlesAndIds(String query) async {
final String animeTitlesAndIdsEndpoint =
"https://www.goyabu.us/busca?busca=$query";
var url = Uri.parse(animeTitlesAndIdsEndpoint);
var response =
await http.get(url, headers: {"Referer": "https://www.goyabu.us/"});

if (response.statusCode != 200) {
return [[], []];
}
List<List<String>> titlesAndIds = [[], []];
String htmlContent = response.body;
var document = parse(htmlContent);

var elements = document.querySelectorAll('.ultimosAnimesHomeItem');
for (var element in elements) {
//link
var id = element.querySelector('a')?.attributes['href'];
//title
var title =
element.querySelector('.ultimosAnimesHomeItemInfosNome')?.text.trim();

if (id != null && title != null) {
titlesAndIds[0].add(title);
titlesAndIds[1].add(id);
}
}
return titlesAndIds;
}

@override
String getSourceName() {
return "Goyabu (Pt -Br)";
}

}
2 changes: 2 additions & 0 deletions lib/sources/sources.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export 'anime/anime_source.dart';
export 'anime/gogoanime_source.dart';
export 'anime/zoro_source.dart';
export 'anime/goyabu.dart';
export 'anime/animes_online_source.dart';
export 'manga/manga_source.dart';
export 'manga/mangahere_source.dart';
10 changes: 5 additions & 5 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,10 @@ packages:
dependency: "direct main"
description:
name: fvp
sha256: e7239f98ccc59db95bb1a73832e720ceb96f4b44aca05bf6d017852e913ad2be
sha256: b692043a7f1a789672f70837879853533fbcb0b4c17b86fffa7c642aeee9f70c
url: "https://pub.dev"
source: hosted
version: "0.16.1"
version: "0.19.0"
get_it:
dependency: transitive
description:
Expand Down Expand Up @@ -425,7 +425,7 @@ packages:
source: hosted
version: "1.0.4"
html:
dependency: transitive
dependency: "direct main"
description:
name: html
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
Expand Down Expand Up @@ -977,10 +977,10 @@ packages:
dependency: "direct main"
description:
name: video_player
sha256: db6a72d8f4fd155d0189845678f55ad2fd54b02c10dcafd11c068dbb631286c0
sha256: aced48e701e24c02b0b7f881a8819e4937794e46b5a5821005e2bf3b40a324cc
url: "https://pub.dev"
source: hosted
version: "2.8.6"
version: "2.8.7"
video_player_android:
dependency: transitive
description:
Expand Down
Loading

0 comments on commit da86fc5

Please sign in to comment.