8000 Add downloader app by ap-atul · Pull Request #33 · ranobe-org/ranobe · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add downloader app #33

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

Merged
merged 2 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,3 @@ local.properties
/app/release/
.idea
beta/

/downloader/
10 changes: 10 additions & 0 deletions core/src/main/java/org/ranobe/core/sources/SourceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import org.ranobe.core.sources.en.AllNovel;
import org.ranobe.core.sources.en.AzyNovel;
import org.ranobe.core.sources.en.BoxNovel;
import org.ranobe.core.sources.en.FreeWebNovel;
import org.ranobe.core.sources.en.LightNovelBtt;
import org.ranobe.core.sources.en.LightNovelHeaven;
import org.ranobe.core.sources.en.LightNovelPub;
import org.ranobe.core.sources.en.LightNovelWorld;
import org.ranobe.core.sources.en.NewNovel;
import org.ranobe.core.sources.en.ReadLightNovel;
import org.ranobe.core.sources.en.ReadWebNovels;
Expand All @@ -18,6 +20,10 @@
import java.util.Map;

public class SourceManager {
private SourceManager() throws IllegalAccessException {
throw new IllegalAccessException("Cannot initialize this class ;)");
}

public static Source getSource(int sourceId) {
try {
Class<?> klass = getSources().get(sourceId);
Expand Down Expand Up @@ -58,6 +64,8 @@ public static Map<Integer, Class<?>> getSources() {
sources.put(11, ReadWebNovels.class);
sources.put(12, BoxNovel.class);
sources.put(13, WuxiaWorld.class);
sources.put(15, LightNovelWorld.class);
sources.put(16, FreeWebNovel.class);

return sources;
}
Expand All @@ -76,6 +84,8 @@ public static Map<String, Class<?>> getSourcesByDomain() {
sources.put("readwebnovels.net", ReadWebNovels.class);
sources.put("boxnovel.com", BoxNovel.class);
sources.put("wuxiaworld.site", WuxiaWorld.class);
sources.put("lightnovelworld.org", LightNovelWorld.class);
sources.put("freewebnovel.com", FreeWebNovel.class);

return sources;
}
Expand Down
129 changes: 129 additions & 0 deletions core/src/main/java/org/ranobe/core/sources/en/FreeWebNovel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package org.ranobe.core.sources.en;


import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.ranobe.core.models.Chapter;
import org.ranobe.core.models.DataSource;
import org.ranobe.core.models.Filter;
import org.ranobe.core.models.Lang;
import org.ranobe.core.models.Novel;
import org.ranobe.core.network.HttpClient;
import org.ranobe.core.sources.Source;
import org.ranobe.core.util.NumberUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class FreeWebNovel implements Source {
private static final String BASE_URL = "https://freewebnovel.com";
private static final int SOURCE_ID = 16;

@Override
public DataSource metadata() {
DataSource source = new DataSource();
source.sourceId = SOURCE_ID;
source.url = BASE_URL;
source.name = "Free Web Novel";
source.lang = Lang.eng;
source.dev = "ap-atul";
source.logo = "https://freewebnovel.com/static/freewebnovel/favicon.ico";
return source;
}

@Override
public List<Novel> novels(int page) throws Exception {
String web = BASE_URL.concat("/latest-release-novels/" + (page + 1) + "/");
return parseNovel(HttpClient.GET(web, new HashMap<>()));
}

private List<Novel> parseNovel(String response) {
List<Novel> items = new ArrayList<>();
Element doc = Jsoup.parse(response);

for (Element element : doc.select("div.li-row")) {
String url = element.select("div.pic > a").attr("href").trim();

if (url.length() > 0) {
Novel item = new Novel(BASE_URL + url);
item.sourceId = SOURCE_ID;
item.name = element.select("div.txt > h3.tit > a").text().trim();
item.cover = element.select("div.pic > a > img").attr("src");
items.add(item);
}
}
return items;
}

@Override
public Novel details(Novel novel) throws Exception {
Element doc = Jsoup.parse(HttpClient.GET(novel.url, new HashMap<>()));

novel.sourceId = SOURCE_ID;
novel.name = doc.select("div.m-desc > h1").text().trim();
novel.cover = doc.select("div.pic > img").attr("src").trim();
novel.summary = String.join("\n\n", doc.select("div.inner > p").eachText());

for (Element element : doc.select("div.txt > div.item")) {
String check = element.select("span").attr("title");
if (check.contains("Status")) {
novel.status = element.select("a").text().trim();
} else if (check.contains("Author")) {
novel.authors = element.select("a").eachText();
} else if (check.contains("Genre")) {
novel.genres = element.select("a").eachText();
}
}

return novel;
}

@Override
public List<Chapter> chapters(Novel novel) throws Exception {
List<Chapter> items = new ArrayList<>();
Element doc = Jsoup.parse(HttpClient.GET(novel.url, new HashMap<>()));

while (true) {
Element next = doc.select("div.page > a:contains(Next)").first();

for (Element element : doc.select("div.m-newest2 > ul.ul-list5 > li")) {
Chapter item = new Chapter(novel.url);

item.url = BASE_URL + element.select("a").attr("href").trim();
item.name = element.select("a").text().trim();
item.id = NumberUtils.toFloat(item.name);
items.add(item);
}

if (next != null) {
String nextUrl = next.attr("href");
doc = Jsoup.parse(HttpClient.GET(BASE_URL + nextUrl, new HashMap<>()));
} else {
break;
}
}

return items;
}

@Override
public Chapter chapter(Chapter chapter) throws Exception {
Element doc = Jsoup.parse(HttpClient.GET(chapter.url, new HashMap<>()));
chapter.content = String.join("\n\n", doc.select("div#article > p").eachText());
return chapter;
}

@Override
public List<Novel> search(Filter filters, int page) throws Exception {
if (filters.hashKeyword() && page == 1) {
String keyword = filters.getKeyword();
String web = BASE_URL + "/search/";
HashMap<String, String> form = new HashMap<>();
form.put("searchkey", keyword);
String response = HttpClient.POST(web, new HashMap<>(), form);
return parseNovel(response);
}
return new ArrayList<>();
}
}
145 changes: 145 additions & 0 deletions core/src/main/java/org/ranobe/core/sources/en/LightNovelWorld.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package org.ranobe.core.sources.en;


import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.ranobe.core.models.Chapter;
import org.ranobe.core.models.DataSource;
import org.ranobe.core.models.Filter;
import org.ranobe.core.models.Lang;
import org.ranobe.core.models.Novel;
import org.ranobe.core.network.HttpClient;
import org.ranobe.core.sources.Source;
import org.ranobe.core.util.NumberUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

public class LightNovelWorld implements Source {
private static final String BASE_URL = "https://lightnovelworld.org";
private static final int SOURCE_ID = 15;

@Override
public DataSource metadata() {
DataSource source = new DataSource();
source.sourceId = SOURCE_ID;
source.url = BASE_URL;
source.name = "Light Novel World";
source.lang = Lang.eng;
source.dev = "ap-atul";
source.logo = "https://lightnovelworld.org/logo.ico";
return source;
}

@Override
public List<Novel> novels(int page) throws Exception {
List<Novel> items = new ArrayList<>();
String web = String.format(Locale.getDefault(), "%s/genre-all/sort-new/status-all/all-novel?page=%d", BASE_URL, page);
Element doc = Jsoup.parse(HttpClient.GET(web, new HashMap<>()));

for (Element element : doc.select("li.novel-item")) {
String url = element.select("a").attr("href").trim();

if (url.length() > 0) {
Novel item = new Novel(url);
item.sourceId = SOURCE_ID;
item.name = element.select("a > h4").text().trim();
item.cover = element.select("a > figure > img").attr("data-src");
items.add(item);
}
}
return items;
}

@Override
public Novel details(Novel novel) throws Exception {
Element doc = Jsoup.parse(HttpClient.GET(novel.url, new HashMap<>()));

novel.sourceId = SOURCE_ID;
novel.name = doc.select("h1[itemprop=name]").text().trim();
novel.cover = doc.select("figure.cover > img").attr("data-src").trim();
novel.summary = String.join("\n\n", doc.select("div.inner > p").eachText());
novel.authors = Collections.singletonList(doc.select("span[itemprop=author]").text());
novel.genres = doc.select("div.categories > ul > li").eachText();

for (Element element : doc.select("div.header-stats > span")) {
if (element.select("small").text().contains("Status")) {
novel.status = element.select("strong").text().trim();
break;
}
}

return novel;
}

@Override
public List<Chapter> chapters(Novel novel) throws Exception {
List<Chapter> items = new ArrayList<>();
String base = novel.url.concat("/chapters");
Element doc = Jsoup.parse(HttpClient.GET(base, new HashMap<>()));

while (true) {
Element next = doc.select("a[rel=next]").first();

for (Element element : doc.select("ul.chapter-list > li")) {
Chapter item = new Chapter(novel.url);

item.url = element.select("a").attr("href").trim();
item.name = element.select("a > strong").text().trim();
item.id = NumberUtils.toFloat(item.name);
items.add(item);
}

if (next != null) {
String nextUrl = next.attr("href");
doc = Jsoup.parse(HttpClient.GET(nextUrl, new HashMap<>()));
} else {
break;
}
}

return items;
}

@Override
public Chapter chapter(Chapter chapter) throws Exception {
Element doc = Jsoup.parse(HttpClient.GET(chapter.url, new HashMap<>()));
chapter.content = String.join("\n\n", doc.select("div#content > p").eachText());
return chapter;
}

@Override
public List<Novel> search(Filter filters, int page) throws Exception {
if (filters.hashKeyword() && page == 1) {
String keyword = filters.getKeyword();
String web = BASE_URL + "/ajax/searchLive?inputContent=" + keyword;
return parseNovel(web);
}
return new ArrayList<>();
}
< 427E /td>
private List<Novel> parseNovel(String web) throws JSONException, IOException {
List<Novel> items = new ArrayList<>();
String response = HttpClient.GET(web, new HashMap<>());
Element doc = Jsoup.parse(new JSONObject(response).getString("html"));

for (Element element : doc.select("li.novel-item")) {
String url = element.select("a").attr("href").trim();

if (url.length() > 0) {
Novel item = new Novel(url);
item.sourceId = SOURCE_ID;
item.name = element.select("a").attr("title").trim();
item.cover = element.select("figure.novel-cover > img").attr("src");
items.add(item);
}
}
return items;
}
}
2 changes: 2 additions & 0 deletions downloader/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build
/release
48 changes: 48 additions & 0 deletions downloader/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
plugins {
id 'com.android.application'
}

android {
namespace 'org.ranobe.downloader'
compileSdk 33

defaultConfig {
applicationId "org.ranobe.downloader"
minSdk 21
targetSdk 33
versionCode 1
versionName "0.1"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}
}

dependencies {
implementation project(path: ':core')
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'com.github.bumptech.glide:glide:4.15.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1'
implementation('nl.siegmann.epublib:epublib-core:3.1') {
exclude group: 'org.slf4j'
exclude group: 'xmlpull'
}
implementation 'org.slf4j:slf4j-android:1.7.25'
implementation 'androidx.navigation:navigation-fragment:2.5.3'
implementation 'androidx.navigation:navigation-ui:2.5.3'
}
7 changes: 7 additions & 0 deletions downloader/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-keep class org.xmlpull.v1.** { *; }

-dontwarn okhttp3.internal.platform.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
-dontwarn org.kxml2.**
Loading
0