Skip to content

Commit

Permalink
Merge pull request #297 from wgh136/dev
Browse files Browse the repository at this point in the history
v2.3.0-hotfix
  • Loading branch information
wgh136 committed Dec 2, 2023
2 parents 8cd7993 + bd3dffb commit 3f74bc6
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 86 deletions.
2 changes: 1 addition & 1 deletion lib/foundation/def.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const String webUA =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36";

//App版本
const appVersion = "2.3.0";
const appVersion = "2.3.0-hotfix";

//定义宽屏设备的临界值
const changePoint = 600;
Expand Down
31 changes: 22 additions & 9 deletions lib/foundation/image_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:html/parser.dart';
import 'package:path_provider/path_provider.dart';
import 'package:dio/dio.dart';
import 'package:pica_comic/foundation/log.dart';
import 'package:pica_comic/network/app_dio.dart';
import 'package:pica_comic/network/eh_network/eh_models.dart';
import 'package:pica_comic/network/eh_network/get_gallery_id.dart';
import 'package:pica_comic/network/hitomi_network/hitomi_models.dart';
Expand Down Expand Up @@ -116,7 +117,7 @@ class ImageManager {
}

/// 获取图片, 适用于没有任何限制的图片链接
Stream<DownloadProgress> getImage(String url) async* {
Stream<DownloadProgress> getImage(String url, [Map<String, String>? headers]) async* {
while (loadingItems[url] != null) {
var progress = loadingItems[url]!;
yield progress;
Expand All @@ -141,7 +142,7 @@ class ImageManager {
sendTimeout: const Duration(seconds: 8),
receiveTimeout: const Duration(seconds: 8),
followRedirects: true,
headers: {
headers: headers ?? {
"user-agent": webUA,
});

Expand All @@ -154,7 +155,7 @@ class ImageManager {
final savePath =
"${(await getTemporaryDirectory()).path}${pathSep}imageCache$pathSep$fileName";
yield DownloadProgress(0, 100, url, savePath);
var dio = Dio(options);
var dio = logDio(options);
if (url.contains("nhentai")) {
dio.interceptors.add(CookieManager(NhentaiNetwork().cookieJar!));
}
Expand Down Expand Up @@ -225,7 +226,7 @@ class ImageManager {
followRedirects: true,
headers: {"user-agent": webUA, "cookie": EhNetwork().cookiesStr});

var dio = Dio(options);
var dio = logDio(options);

// Get imgKey
const urlsOnePage = 40;
Expand Down Expand Up @@ -276,12 +277,24 @@ class ImageManager {
"showkey": gallery.auth!["showKey"]
});

var image = const JsonDecoder().convert(apiRes.data)["i3"] as String;
var apiJson = const JsonDecoder().convert(apiRes.data);

var i6 = apiJson["i6"] as String;

var originImage = i6.split("<a href=\"").last.split("\">").first;

var image = apiJson["i3"] as String;
image = image.substring(
image.indexOf("src=\"") + 5, image.indexOf("\" style") - 1);

if (image.contains("/img/509.gif")) {
throw ImageExceedError();
}
image = image.substring(
image.indexOf("src=\"") + 5, image.indexOf("\" style") - 1);

if(appdata.settings[29] == "1"){
image = originImage;
}

var res = await dio.get<ResponseBody>(image,
options: Options(responseType: ResponseType.stream));

Expand Down Expand Up @@ -364,7 +377,7 @@ class ImageManager {
var fileName = image.hash + url.substring(l);
final savePath =
"${(await getTemporaryDirectory()).path}${pathSep}imageCache$pathSep$fileName";
var dio = Dio();
var dio = logDio();
dio.options.headers = {
"User-Agent": webUA,
"Referer": "https://hitomi.la/reader/$galleryId.html"
Expand Down Expand Up @@ -461,7 +474,7 @@ class ImageManager {
final savePath =
"${(await getTemporaryDirectory()).path}${pathSep}imageCache$pathSep$fileName";

var dio = Dio();
var dio = logDio();
yield DownloadProgress(0, 1, url, savePath);

var bytes = <int>[];
Expand Down
56 changes: 47 additions & 9 deletions lib/foundation/local_favorites.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:dio/dio.dart';
Expand All @@ -7,6 +8,7 @@ import 'package:path_provider/path_provider.dart';
import 'package:pica_comic/base.dart';
import 'package:pica_comic/foundation/app.dart';
import 'package:pica_comic/foundation/log.dart';
import 'package:pica_comic/network/app_dio.dart';
import 'package:pica_comic/network/eh_network/eh_main_network.dart';
import 'package:pica_comic/network/eh_network/eh_models.dart';
import 'package:pica_comic/network/eh_network/get_gallery_id.dart';
Expand Down Expand Up @@ -193,7 +195,7 @@ class LocalFavoritesManager {
await clearAll();

for (var folder in allComics.keys) {
createFolder(folder);
createFolder(folder, true);
var comics = allComics[folder]!;
for (int i = 0; i < comics.length; i++) {
addComic(folder, comics[i]);
Expand Down Expand Up @@ -238,12 +240,28 @@ class LocalFavoritesManager {
}

/// create a folder
void createFolder(String name) {
void createFolder(String name, [bool renameWhenInvalidName = false]) {
if(name.isEmpty){
throw "name is empty!";
if(renameWhenInvalidName) {
int i = 0;
while (folderNames.contains(i.toString())) {
i++;
}
name = i.toString();
} else {
throw "name is empty!";
}
}
if (folderNames.contains(name)) {
throw Exception("Folder is existing");
if(renameWhenInvalidName) {
int i = 0;
while (folderNames.contains(i.toString())) {
i++;
}
name = i.toString();
} else {
throw Exception("Folder is existing");
}
}
_db.execute("""
create table "$name"(
Expand Down Expand Up @@ -319,16 +337,25 @@ class LocalFavoritesManager {
}
}

int _loading = 0;

/// get comic cover
Future<File> getCover(FavoriteItem item) async {
var path = "${appdataPath!}${pathSep}favoritesCover";
var path = "${appdataPath!}/favoritesCover";
var hash =
md5.convert(const Utf8Encoder().convert(item.coverPath)).toString();
var file = File("$path$pathSep$hash.jpg");
md5.convert(const Utf8Encoder().convert(item.coverPath)).toString();
var file = File("$path/$hash.jpg");
if (file.existsSync()) {
return file;
} else {
var dio = Dio(BaseOptions(headers: {
}
if(item.type == ComicType.ehentai) {
while (_loading > 2) {
await Future.delayed(const Duration(milliseconds: 200));
}
_loading++;
}
try {
var dio = logDio(BaseOptions(headers: {
if (item.type == ComicType.ehentai) "cookie": EhNetwork().cookiesStr,
if (item.type == ComicType.ehentai || item.type == ComicType.hitomi)
"User-Agent": webUA,
Expand All @@ -337,8 +364,19 @@ class LocalFavoritesManager {
var res = await dio.get<Uint8List>(item.coverPath);
file.createSync(recursive: true);
file.writeAsBytesSync(res.data!);
var awaitTime = Random().nextInt(500) + 500;
await Future.delayed(Duration(milliseconds: awaitTime));
return file;
}
catch(e){
await Future.delayed(const Duration(seconds: 5));
rethrow;
}
finally{
if(item.type == ComicType.ehentai) {
_loading--;
}
}
}

/// delete a folder
Expand Down
79 changes: 48 additions & 31 deletions lib/network/app_dio.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,17 @@ class MyLogInterceptor implements Interceptor {
}

class AppHttpAdapter implements HttpClientAdapter{
final adapter = IOHttpClientAdapter();
final HttpClientAdapter adapter;

AppHttpAdapter(bool http2):
adapter = http2 ? Http2Adapter(ConnectionManager(
idleTimeout: const Duration(seconds: 10),
onClientCreate: (_, config) {
if (proxyHttpOverrides?.proxyStr != null) {
config.proxy = Uri.parse('http://${proxyHttpOverrides?.proxyStr}');
}
},
),) : IOHttpClientAdapter();

@override
void close({bool force = false}) {
Expand Down Expand Up @@ -63,6 +73,20 @@ class AppHttpAdapter implements HttpClientAdapter{
}
}

void changeHost(RequestOptions options){
var config = const JsonDecoder().convert(File("${App.dataPath}/hosts.json").readAsStringSync());
if(config["https"][options.uri.host] != null){
LogManager.addLog(LogLevel.info, "Network",
"Change host from ${options.uri.host} to ${config["https"][options.uri.host]}");
options.path = options.path.replaceFirst(options.uri.host, config["https"][options.uri.host]!);
} else if(config["http"][options.uri.host] != null){
LogManager.addLog(LogLevel.info, "Network",
"Change host from ${options.uri.host} to ${config["http"][options.uri.host]}");
options.path = options.path.replaceFirst(options.uri.host, config["http"][options.uri.host]!);
options.path = options.path.replaceFirst("https://", "http://");
}
}

@override
Future<ResponseBody> fetch(RequestOptions o, Stream<Uint8List>? requestStream, Future<void>? cancelFuture) async{
var options = o.copyWith();
Expand All @@ -72,28 +96,34 @@ class AppHttpAdapter implements HttpClientAdapter{
return await adapter.fetch(options, requestStream, cancelFuture);
}
createConfigFile();
var config = const JsonDecoder().convert(File("${App.dataPath}/hosts.json").readAsStringSync());
if(options.headers["host"] == null && options.headers["Host"] == null){
options.headers["host"] = options.uri.host;
}
if(config["https"][options.uri.host] != null){
LogManager.addLog(LogLevel.info, "Network",
"Change host from ${options.uri.host} to ${config["https"][options.uri.host]}");
options.path = options.path.replaceFirst(options.uri.host, config["https"][options.uri.host]!);
} else if(config["http"][options.uri.host] != null){
LogManager.addLog(LogLevel.info, "Network",
"Change host from ${options.uri.host} to ${config["http"][options.uri.host]}");
options.path = options.path.replaceFirst(options.uri.host, config["http"][options.uri.host]!);
options.path = options.path.replaceFirst("https://", "http://");
}
changeHost(options);
options.followRedirects = false;
var res = await adapter.fetch(options, requestStream, cancelFuture);
if(res.statusCode == 302){
while(res.statusCode == 302){
var location = res.headers["location"]!.first;
options.path = options.path.contains("https://")
? "https://${options.uri.host}$location"
: "http://${options.uri.host}$location";
return await adapter.fetch(options, requestStream, cancelFuture);
if(location.contains("http") && Uri.tryParse(location) != null){
if(Uri.parse(location).host != o.uri.host){
options.path = location;
changeHost(options);
res = await adapter.fetch(options, requestStream, cancelFuture);
} else {
location = Uri
.parse(location)
.path;
options.path = options.path.contains("https://")
? "https://${options.uri.host}$location"
: "http://${options.uri.host}$location";
res = await adapter.fetch(options, requestStream, cancelFuture);
}
} else {
options.path = options.path.contains("https://")
? "https://${options.uri.host}$location"
: "http://${options.uri.host}$location";
res = await adapter.fetch(options, requestStream, cancelFuture);
}
}
return res;
}
Expand All @@ -102,20 +132,7 @@ class AppHttpAdapter implements HttpClientAdapter{

Dio logDio([BaseOptions? options, bool http2 = false]) {
var dio = Dio(options)..interceptors.add(MyLogInterceptor());
if (http2) {
dio.httpClientAdapter = Http2Adapter(
ConnectionManager(
idleTimeout: const Duration(seconds: 10),
onClientCreate: (_, config) {
if (proxyHttpOverrides?.proxyStr != null) {
config.proxy = Uri.parse('http://${proxyHttpOverrides?.proxyStr}');
}
},
),
);
} else {
dio.httpClientAdapter = AppHttpAdapter();
}
dio.httpClientAdapter = AppHttpAdapter(http2);
return dio;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/network/download.dart
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ class DownloadManager{
comic = DownloadedHitomiComic.fromMap(jsonDecode(json));
} else if (id.startsWith("nhentai")) {
comic = NhentaiDownloadedComic.fromJson(jsonDecode(json));
} else if (id.startsWith("ht")) {
} else if (id.startsWith("Ht")) {
comic = DownloadedHtComic.fromJson(jsonDecode(json));
} else if (id.isNum) {
comic = DownloadedGallery.fromJson(jsonDecode(json));
Expand Down
9 changes: 8 additions & 1 deletion lib/network/eh_network/eh_main_network.dart
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ class EhNetwork {
...?headers
});

var dio = Dio(options)..interceptors.add(LogInterceptor());
var dio = logDio(options);

try {
var res = await dio.post<String>(ehApiUrl, data: data);
Expand Down Expand Up @@ -548,13 +548,20 @@ class EhNetwork {
}
}

Set<String> loadingReaderLinks = {};

/// page starts from 1
Future<Res<List<String>>> getReaderLinks(String link, int page) async {
String url = "$link?inline_set=ts_m";
while(loadingReaderLinks.contains(url)){
await Future.delayed(const Duration(milliseconds: 200));
}
loadingReaderLinks.add(url);
if (page != 1) {
url = "$url&p=${page - 1}";
}
var res = await request(url);
loadingReaderLinks.remove(url);
if (res.error) {
return Res(null, errorMessage: res.errorMessage);
}
Expand Down
13 changes: 6 additions & 7 deletions lib/network/picacg_network/methods.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ class PicacgNetwork {

Future<Res<Map<String, dynamic>>> post(
String url, Map<String, String>? data) async {
var api = appdata.settings[3] == "1"
? "$serverDomain/picaapi"
: "https://picaapi.picacomic.com";
var api = "https://picaapi.picacomic.com";
if (token == "" &&
url != '$api/auth/sign-in' &&
url != "https://picaapi.picacomic.com/auth/register") {
Expand Down Expand Up @@ -142,9 +140,10 @@ class PicacgNetwork {

///登录
Future<Res<bool>> login(String email, String password) async {
var api = appdata.settings[3] == "1"
? "$serverDomain/picaapi"
: "https://picaapi.picacomic.com";
if(token.isNotEmpty){
token = "";
}
var api = "https://picaapi.picacomic.com";
var response = await post('$api/auth/sign-in', {
"email": email,
"password": password,
Expand All @@ -157,7 +156,7 @@ class PicacgNetwork {
try {
token = res["data"]["token"];
} catch (e) {
return const Res(null, errorMessage: "Failed to get token");
return const Res(null, errorMessage: "Failed to get token\n");
}
if (kDebugMode) {
print("Logging successfully");
Expand Down
Loading

0 comments on commit 3f74bc6

Please sign in to comment.