fixed no result found error

This commit is contained in:
dstark5
2023-11-03 06:05:03 -07:00
parent 3a95d79c4a
commit 51283c3410
8 changed files with 194 additions and 160 deletions

View File

@ -19,13 +19,15 @@
<data android:scheme="https" />
</intent>
</queries>
<application
android:label="Openlib"
android:name="${applicationName}"
android:usesCleartextTraffic="true"
android:requestLegacyExternalStorage="true"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
android:icon="@mipmap/launcher_icon">
<activity
android:name=".MainActivity"
android:exported="true"
@ -38,6 +40,7 @@
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"

View File

@ -2,7 +2,6 @@ import 'package:dio/dio.dart';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:html/parser.dart' show parse;
import 'package:http/http.dart' as http;
class BookData {
final String title;
@ -52,10 +51,12 @@ class BookInfoData extends BookData {
class AnnasArchieve {
String baseUrl = "https://annas-archive.org";
final Dio dio = Dio(BaseOptions(headers: {
final Dio dio = Dio();
Map<String, dynamic> defaultDioHeaders = {
"user-agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
}));
};
String getMd5(String url) {
String md5 = url.toString().split('/').last;
@ -66,7 +67,7 @@ class AnnasArchieve {
var document =
parse(resData.toString().replaceAll(RegExp(r"<!--|-->"), ''));
var books = document.querySelectorAll(
'a[class="js-vim-focus custom-a flex items-center relative left-[-10px] w-[calc(100%+20px)] px-[10px] py-2 outline-offset-[-2px] outline-2 rounded-[3px] hover:bg-[#00000011] focus:outline "]');
'a[class="js-vim-focus custom-a flex items-center relative left-[-10px] w-[calc(100%+20px)] px-[10px] outline-offset-[-2px] outline-2 rounded-[3px] hover:bg-[#00000011] focus:outline "]');
List<BookData> bookList = [];
@ -75,16 +76,23 @@ class AnnasArchieve {
'title': element.querySelector('h3')?.text,
'thumbnail': element.querySelector('img')?.attributes['src'],
'link': element.attributes['href'],
'author': element.querySelector('div[class="truncate italic"]')?.text ??
'author': element
.querySelector(
'div[class="max-lg:line-clamp-[2] lg:truncate leading-[1.2] lg:leading-[1.35] max-lg:text-sm italic"]')
?.text ??
'unknown',
'publisher':
element.querySelector('div[class="truncate text-sm"]')?.text ??
"unknown",
'publisher': element
.querySelector(
'div[class="truncate leading-[1.2] lg:leading-[1.35] max-lg:text-xs"]')
?.text ??
"unknown",
'info': element
.querySelector('div[class="truncate text-xs text-gray-500"]')
.querySelector(
'div[class="line-clamp-[2] leading-[1.2] text-[10px] lg:text-xs text-gray-500"]')
?.text ??
''
};
if ((data['title'] != null && data['title'] != '') &&
(data['link'] != null && data['link'] != '') &&
(data['info'] != null &&
@ -130,19 +138,29 @@ class AnnasArchieve {
Future<String?> _getMirrorLink(
String url, String userAgent, String cookie) async {
try {
final response = await http.get(Uri.parse(url),
headers: {"Cookie": cookie, "User-Agent": userAgent});
if (response.statusCode == 403) {
throw jsonEncode({"code": "403", "url": url});
}
var document = parse(response.body.toString());
final response = await dio.get(url,
options: Options(extra: {
'withCredentials': true
}, headers: {
"Host": "annas-archive.org",
"Origin": "https://annas-archive.org",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "secure",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-site",
"Cookie": cookie,
"User-Agent": userAgent
}));
var document = parse(response.data.toString());
var pTag = document.querySelector('p[class="mb-4"]');
String? link = pTag?.querySelector('a')?.attributes['href'];
return link;
} catch (e) {
// print(e);
// print('${url} ${e}');
if (e.toString().contains("403")) {
rethrow;
throw jsonEncode({"code": "403", "url": url});
}
return null;
}
@ -238,7 +256,8 @@ class AnnasArchieve {
? '$baseUrl/search?index=&q=$searchQuery&ext=$fileType&sort=$sort'
: '$baseUrl/search?index=&q=$searchQuery&content=$content&ext=$fileType&sort=$sort';
final response = await dio.get(encodedURL);
final response = await dio.get(encodedURL,
options: Options(headers: defaultDioHeaders));
return _parser(response.data, fileType);
} on DioException catch (e) {
if (e.type == DioExceptionType.unknown) {
@ -253,7 +272,8 @@ class AnnasArchieve {
required String userAgent,
required String cookie}) async {
try {
final response = await dio.get(url);
final response =
await dio.get(url, options: Options(headers: defaultDioHeaders));
BookInfoData? data =
await _bookInfoParser(response.data, url, userAgent, cookie);
if (data != null) {

View File

@ -1,5 +1,4 @@
import 'package:dio/dio.dart';
import 'package:http/http.dart' as http;
import 'files.dart';
Future<String> _getFilePath(String fileName) async {
@ -24,11 +23,11 @@ List<String> _reorderMirrors(List<String> mirrors) {
return [...ipfsMirrors, ...httpsMirrors];
}
Future<String?> _getAliveMirror(List<String> mirrors) async {
Future<String?> _getAliveMirror(List<String> mirrors, Dio dio) async {
for (var url in mirrors) {
try {
final response =
await http.head(Uri.parse(url)).timeout(const Duration(seconds: 2));
final response = await dio.head(url,
options: Options(receiveTimeout: const Duration(seconds: 5)));
if (response.statusCode == 200) {
return url;
}
@ -48,10 +47,11 @@ Future<void> downloadFile(
required Function mirrorStatus,
required Function onDownlaodFailed}) async {
Dio dio = Dio();
String path = await _getFilePath('$md5.$format');
List<String> orderedMirrors = _reorderMirrors(mirrors);
String? workingMirror = await _getAliveMirror(orderedMirrors);
String? workingMirror = await _getAliveMirror(orderedMirrors, dio);
// print(workingMirror);
// print(path);

View File

@ -1,8 +1,8 @@
import 'package:dio/dio.dart';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:openlib/services/database.dart';
import 'package:openlib/ui/components/error_widget.dart';
@ -48,23 +48,21 @@ class BookInfoPage extends ConsumerWidget {
data: data, child: ActionButtonWidget(data: data));
},
error: (err, _) {
// print(err);
if (err.toString().contains("403")) {
var errJson = jsonDecode(err.toString());
if (SchedulerBinding.instance.schedulerPhase ==
SchedulerPhase.persistentCallbacks) {
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) {
return Webview(url: errJson["url"]);
})).then((value) {
// print("got Cf Clearance");
// ignore: unused_result
ref.refresh(bookInfoProvider(url));
// });
});
Future.delayed(
const Duration(seconds: 3),
() => Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext context) {
return Webview(url: errJson["url"]);
})));
});
}
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
@ -112,7 +110,7 @@ class BookInfoPage extends ConsumerWidget {
child: const Padding(
padding: EdgeInsets.all(10.0),
child: Text(
"If you have solved the captcha then you will be automatically redirected to the book page",
"If you have solved the captcha then you will be automatically redirected to the results page . In case you seeing this page even after completing try using a VPN .",
textAlign: TextAlign.start,
style: TextStyle(
fontSize: 13,

View File

@ -17,127 +17,133 @@ class TrendingPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final trendingBooks = ref.watch(getTrendingBooks);
return trendingBooks.when(data: (data) {
return Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 10),
child: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: [
const SliverToBoxAdapter(
child: TitleText("Trending"),
),
SliverPadding(
padding: const EdgeInsets.all(5),
sliver: SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10.0,
crossAxisSpacing: 13.0,
mainAxisExtent: 205,
return trendingBooks.when(
skipLoadingOnRefresh: false,
data: (data) {
return Padding(
padding: const EdgeInsets.only(left: 5, right: 5, top: 10),
child: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: [
const SliverToBoxAdapter(
child: TitleText("Trending"),
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return InkWell(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) {
return ResultPage(
searchQuery: data[index].title!,
);
}));
},
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CachedNetworkImage(
height: imageHeight,
width: imageWidth,
imageUrl: data[index].thumbnail!,
imageBuilder: (context, imageProvider) =>
Container(
decoration: BoxDecoration(
boxShadow: const [
BoxShadow(
color: Colors.grey,
spreadRadius: 0.1,
blurRadius: 1)
],
borderRadius: const BorderRadius.all(
Radius.circular(5)),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.fill,
),
),
),
placeholder: (context, url) => Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: "#E3E8E9".toColor(),
),
height: imageHeight,
width: imageWidth,
),
errorWidget: (context, url, error) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.grey,
),
SliverPadding(
padding: const EdgeInsets.all(5),
sliver: SliverGrid(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10.0,
crossAxisSpacing: 13.0,
mainAxisExtent: 205,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return InkWell(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (BuildContext context) {
return ResultPage(
searchQuery: data[index].title!,
);
}));
},
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CachedNetworkImage(
height: imageHeight,
width: imageWidth,
child: const Center(
child: Icon(Icons.image_rounded),
imageUrl: data[index].thumbnail!,
imageBuilder: (context, imageProvider) =>
Container(
decoration: BoxDecoration(
boxShadow: const [
BoxShadow(
color: Colors.grey,
spreadRadius: 0.1,
blurRadius: 1)
],
borderRadius: const BorderRadius.all(
Radius.circular(5)),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.fill,
),
),
),
);
},
),
Padding(
padding: const EdgeInsets.only(top: 4),
child: SizedBox(
width: imageWidth,
child: Text(
data[index].title!,
style: Theme.of(context)
.textTheme
.displayMedium,
maxLines: 2,
placeholder: (context, url) => Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: "#E3E8E9".toColor(),
),
height: imageHeight,
width: imageWidth,
),
errorWidget: (context, url, error) {
return Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(5),
color: Colors.grey,
),
height: imageHeight,
width: imageWidth,
child: const Center(
child: Icon(Icons.image_rounded),
),
);
},
),
),
),
]),
),
);
},
childCount: data.length,
Padding(
padding: const EdgeInsets.only(top: 4),
child: SizedBox(
width: imageWidth,
child: Text(
data[index].title!,
style: Theme.of(context)
.textTheme
.displayMedium,
maxLines: 2,
),
),
),
]),
),
);
},
childCount: data.length,
),
),
),
),
],
),
],
),
);
}, error: (error, _) {
return CustomErrorWidget(
error: error,
stackTrace: _,
onRefresh: () {
// ignore: unused_result
ref.refresh(getTrendingBooks);
);
},
);
}, loading: () {
return Center(
child: SizedBox(
width: 25,
height: 25,
child: CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary,
),
));
});
error: (error, _) {
return CustomErrorWidget(
error: error,
stackTrace: _,
onRefresh: () {
// ignore: unused_result
ref.refresh(getTrendingBooks);
},
);
},
loading: () {
return Center(
child: SizedBox(
width: 25,
height: 25,
child: CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary,
),
));
});
}
}

View File

@ -5,7 +5,7 @@ import 'package:webview_cookie_manager/webview_cookie_manager.dart'
as cookiejar;
import 'package:openlib/state/state.dart'
show cookieProvider, userAgentProvider, dbProvider;
show cookieProvider, userAgentProvider, dbProvider, bookInfoProvider;
class Webview extends ConsumerStatefulWidget {
const Webview({Key? key, required this.url}) : super(key: key);
@ -38,12 +38,13 @@ class _WebviewState extends ConsumerState<Webview> {
})
..setNavigationDelegate(NavigationDelegate(
onPageStarted: (url) async {
var x = await controller.runJavaScriptReturningResult(
var urlStatusCode = await controller.runJavaScriptReturningResult(
"var xhr = new XMLHttpRequest();xhr.open('GET', window.location.href, false);xhr.send(null);xhr.status;");
if (x.toString().contains('200')) {
if (urlStatusCode.toString().contains('200')) {
final cookies = await cookieManager
.getCookies("https://annas-archive.org");
List<String> cookie = [];
for (var element in cookies) {
if (element.name == 'cf_clearance' ||
@ -51,10 +52,17 @@ class _WebviewState extends ConsumerState<Webview> {
cookie.add(element.toString().split(';')[0]);
}
}
ref.read(cookieProvider.notifier).state = cookie.join('; ');
ref
String cfClearance = cookie.join('; ');
ref.read(cookieProvider.notifier).state = cfClearance;
await ref
.read(dbProvider)
.setBrowserOptions('cookie', cookie.join('; '));
.setBrowserOptions('cookie', cfClearance);
ref.invalidate(bookInfoProvider);
// ignore: use_build_context_synchronously
Navigator.pop(context);
}

View File

@ -305,7 +305,7 @@ packages:
source: hosted
version: "0.15.4"
http:
dependency: "direct main"
dependency: transitive
description:
name: http
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"

View File

@ -47,7 +47,6 @@ dependencies:
path_provider: ^2.0.15
permission_handler: ^10.4.3
open_file: ^3.3.2
http: ^1.1.0
webview_flutter: ^4.4.1
webview_cookie_manager: ^2.0.6