Created
August 9, 2022 09:27
-
-
Save FlafyDev/9f5f03903addfdb94e60ea167e345fb8 to your computer and use it in GitHub Desktop.
ZLibrary metadata and downloader for my book reader.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:epub_reader/providers/book_downloader/zlibrary_book_downloader.dart'; | |
import 'package:http/http.dart'; | |
import '../../models/book.dart'; | |
abstract class BookDownloader { | |
Client httpClient; | |
BookDownloader({required this.httpClient}); | |
Future<Uri?> getEpubDownload(BookIdentifier bookIdentifier); | |
} | |
enum BookDownloaderEnum { | |
none, | |
zlibrary, | |
} | |
extension BookDownloaderEnumExtension on BookDownloaderEnum { | |
String get name { | |
switch (this) { | |
case BookDownloaderEnum.none: | |
return 'None'; | |
case BookDownloaderEnum.zlibrary: | |
return 'ZLibrary'; | |
} | |
} | |
} | |
Future<BookDownloader?> createBookDownloader( | |
BookDownloaderEnum bookDownloader) async { | |
switch (bookDownloader) { | |
case BookDownloaderEnum.none: | |
return null; | |
case BookDownloaderEnum.zlibrary: | |
return ZLibraryBookDownloader(httpClient: Client()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:epub_reader/models/book.dart'; | |
import 'package:epub_reader/providers/book_metadata/zlibrary_book_metadata.dart'; | |
import 'package:http/http.dart'; | |
abstract class BookMetadata { | |
Client httpClient; | |
BookMetadata({required this.httpClient}); | |
Future<List<Book>> searchBooks(String query); | |
Future<Book?> getBookData(BookIdentifier bookIdentifier); | |
} | |
enum BookMetadataEnum { | |
none, | |
zlibrary, | |
} | |
extension BookMetadataEnumExtension on BookMetadataEnum { | |
String get name { | |
switch (this) { | |
case BookMetadataEnum.none: | |
return 'None'; | |
case BookMetadataEnum.zlibrary: | |
return 'ZLibrary'; | |
} | |
} | |
} | |
Future<BookMetadata?> createBookMetadata(BookMetadataEnum bookMetadata) async { | |
switch (bookMetadata) { | |
case BookMetadataEnum.none: | |
return null; | |
case BookMetadataEnum.zlibrary: | |
return ZLibraryBookMetadata(httpClient: Client()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:epub_reader/models/book.dart'; | |
import 'package:html/parser.dart'; | |
import 'package:http/http.dart'; | |
import '../book_metadata/zlibrary_book_metadata.dart'; | |
import 'book_downloader.dart'; | |
class ZLibraryBookDownloader extends BookDownloader { | |
ZLibraryBookMetadata zLibraryBookMetadata; | |
ZLibraryBookDownloader({required Client httpClient}) | |
: zLibraryBookMetadata = ZLibraryBookMetadata(httpClient: httpClient), | |
super(httpClient: httpClient); | |
@override | |
Future<Uri?> getEpubDownload(BookIdentifier bookIdentifier) async { | |
String? id = bookIdentifier.other["zlibrary"]; | |
if (id == null) { | |
final isbn = bookIdentifier.getAnyIsbn(); | |
if (isbn == null) { | |
return null; | |
} | |
final books = await zLibraryBookMetadata.searchBooks(isbn); | |
if (books.isEmpty) { | |
return null; | |
} | |
id = books.first.bookIdentifier.other["zlibrary"]; | |
} | |
final rawHtml = (await httpClient | |
.get(zLibraryBookMetadata.baseUri.replace(path: "$id"))) | |
.body; | |
final document = parse(rawHtml); | |
final downloadLinks = document.body! | |
.querySelectorAll('[href]') | |
.where((elem) => | |
elem.attributes["href"]!.contains("/dl/") && | |
elem.text.toLowerCase().contains("epub")) | |
.map((elem) => zLibraryBookMetadata.baseUri | |
.replace(path: elem.attributes["href"]!)); | |
if (downloadLinks.isEmpty) { | |
return null; | |
} | |
return downloadLinks.first; | |
// String rawHtml = | |
// (await httpClient.get(baseUri.replace(path: "s/$isbn"))).body; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:epub_reader/models/book.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:http/http.dart'; | |
import 'book_metadata.dart'; | |
import 'package:html/parser.dart' show parse; | |
import 'package:html/dom.dart' as dom; | |
class ZLibraryBookMetadata extends BookMetadata { | |
Uri baseUri = Uri.https("b-ok.asia", ""); | |
ZLibraryBookMetadata({required Client httpClient}) | |
: super(httpClient: httpClient); | |
@override | |
Future<Book?> getBookData(BookIdentifier bookIdentifier) async { | |
String rawHtml = (await httpClient | |
.get(baseUri.replace(path: "${bookIdentifier.other["zlibrary"]}"))) | |
.body; | |
final document = parse(rawHtml); | |
final body = document.body!; | |
final isbns = body.getElementsByClassName("property_isbn"); | |
return Book( | |
name: body.querySelector('[itemprop="name"]')?.text.trim() ?? "No title", | |
authors: body | |
.querySelectorAll('[itemprop="author"]') | |
.map((authorElem) => authorElem.text) | |
.toList(), | |
description: | |
body.querySelector('[id="bookDescriptionBox"]')?.text.trim() ?? "", | |
coverProvider: NetworkImage(body | |
.getElementsByClassName("details-book-cover")[0] | |
.attributes["href"]!), | |
bookIdentifier: BookIdentifier( | |
isbn10: _findIsbnFromList(isbns, 10), | |
isbn13: _findIsbnFromList(isbns, 13), | |
other: { | |
"zlibrary": bookIdentifier.other["zlibrary"], | |
}, | |
), | |
); | |
} | |
String? _findIsbnFromList(List<dom.Element> list, int length) { | |
return list | |
.map<String?>( | |
(elem) => elem.children[1].text, | |
) | |
.firstWhere( | |
(isbn) => isbn?.length == length, | |
orElse: () => null, | |
); | |
} | |
// Uri( | |
// scheme: "https", | |
// host: "b-ok.asia", | |
// ) | |
@override | |
Future<List<Book>> searchBooks(String query) async { | |
String rawHtml = | |
(await httpClient.get(baseUri.replace(path: "s/$query"))).body; | |
final document = parse(rawHtml); | |
final books = document.getElementsByClassName("bookRow"); | |
return books.map((book) { | |
final coverUrl = book.querySelector('img')?.attributes["data-src"]; | |
return Book( | |
name: | |
book.querySelector('[itemprop="name"]')?.text.trim() ?? "No title", | |
authors: book | |
.querySelectorAll('[itemprop="author"]') | |
.map((authorElem) => authorElem.text) | |
.toList(), | |
description: "", | |
coverProvider: | |
coverUrl != null && !coverUrl.contains("cover-not-exists") | |
? NetworkImage(coverUrl) | |
: null, | |
pages: 1, | |
bookIdentifier: BookIdentifier( | |
isbn13: book | |
.querySelector(".checkBookDownloaded") | |
?.attributes["data-isbn"], | |
other: { | |
"zlibrary": | |
book.querySelector('[itemprop="name"] > a')?.attributes["href"], | |
}, | |
), | |
); | |
}).toList(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment