From b9daf608ff832109fc5c31936889100feeac9eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=99=BD-=E7=99=BD?= Date: Wed, 4 Jan 2023 11:40:40 +0800 Subject: [PATCH] Add more info for torrent download --- .../com/hippo/ehviewer/client/EhEngine.java | 6 +- .../ehviewer/client/parser/TorrentParser.java | 129 ++++++++++++++++-- .../ehviewer/ui/scene/GalleryDetailScene.java | 22 ++- .../main/res/layout/item_select_dialog.xml | 3 +- 4 files changed, 132 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java index fd39799c8..d8ce5ac27 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java @@ -649,8 +649,8 @@ public class EhEngine { return result; } - public static Pair[] getTorrentList(@Nullable EhClient.Task task, OkHttpClient okHttpClient, - String url, long gid, String token) throws Throwable { + public static List getTorrentList(@Nullable EhClient.Task task, OkHttpClient okHttpClient, + String url, long gid, String token) throws Throwable { String referer = EhUrl.getGalleryDetailUrl(gid, token); Log.d(TAG, url); Request request = new EhRequestBuilder(url, referer).build(); @@ -663,7 +663,7 @@ public class EhEngine { String body = null; Headers headers = null; - Pair[] result; + List result; int code = -1; try (Response response = call.execute()) { code = response.code(); diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/TorrentParser.java b/app/src/main/java/com/hippo/ehviewer/client/parser/TorrentParser.java index c66b9d2ac..314eeac67 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/TorrentParser.java +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/TorrentParser.java @@ -16,27 +16,132 @@ package com.hippo.ehviewer.client.parser; -import android.util.Pair; +import androidx.annotation.NonNull; + +import org.jsoup.Jsoup; import java.util.ArrayList; import java.util.List; +import java.util.Objects; +import java.util.function.IntFunction; import java.util.regex.Matcher; import java.util.regex.Pattern; public class TorrentParser { - private static final Pattern PATTERN_TORRENT = Pattern.compile("   ([^<]+)"); + private static final Pattern PATTERN_TORRENT = Pattern.compile(" ([0-9-]+) [0-9:]+[\\s\\S]+ ([0-9\\.]+ [KMGT]B)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+ ([0-9]+)[\\s\\S]+([^<]+)[\\s\\S]+onclick=\"document.location='([^\"]+)'[^<]+>([^<]+)"); - @SuppressWarnings("unchecked") - public static Pair[] parse(String body) { - List> torrentList = new ArrayList<>(); - Matcher m = PATTERN_TORRENT.matcher(body); - while (m.find()) { - String url = ParserUtils.trim(m.group(1)); - String name = ParserUtils.trim(m.group(2)); - Pair item = new Pair<>(url, name); - torrentList.add(item); + public static List parse(String body) { + var torrentList = new ArrayList(); + var d = Jsoup.parse(body); + var es = d.select("form>div>table"); + for (var e : es) { + Matcher m = PATTERN_TORRENT.matcher(e.html()); + if (m.find()) { + String posted = m.group(1); + String size = m.group(2); + int seeds = Integer.parseInt(m.group(3)); + int peers = Integer.parseInt(m.group(4)); + int downloads = Integer.parseInt(m.group(5)); + String uploader = ParserUtils.trim(m.group(6)); + String url = ParserUtils.trim(m.group(7)); + String name = ParserUtils.trim(m.group(8)); + var item = new Result(posted, size, seeds, peers, downloads, uploader, url, name); + torrentList.add(item); + } + } + return torrentList; + } + + public static final class Result { + private final String posted; + private final String size; + private final int seeds; + private final int peers; + private final int downloads; + private final String uploader; + private final String url; + private final String name; + + public Result(String posted, String size, int seeds, int peers, int downloads, String uploader, String url, String name) { + this.posted = posted; + this.size = size; + this.seeds = seeds; + this.peers = peers; + this.downloads = downloads; + this.uploader = uploader; + this.url = url; + this.name = name; + } + + public String format(IntFunction getString) { + return String.format("[%s] %s [%s] [↑%s ↓%s ✓%s]", posted, name, size, seeds, peers, downloads); + } + + public String posted() { + return posted; + } + + public String size() { + return size; + } + + public int seeds() { + return seeds; + } + + public int peers() { + return peers; + } + + public int downloads() { + return downloads; + } + + public String uploader() { + return uploader; + } + + public String url() { + return url; + } + + public String name() { + return name; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (Result) obj; + return Objects.equals(this.posted, that.posted) && + Objects.equals(this.size, that.size) && + this.seeds == that.seeds && + this.peers == that.peers && + this.downloads == that.downloads && + Objects.equals(this.uploader, that.uploader) && + Objects.equals(this.url, that.url) && + Objects.equals(this.name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(posted, size, seeds, peers, downloads, uploader, url, name); + } + + @NonNull + @Override + public String toString() { + return "Result[" + + "posted=" + posted + ", " + + "size=" + size + ", " + + "seeds=" + seeds + ", " + + "peers=" + peers + ", " + + "downloads=" + downloads + ", " + + "uploader=" + uploader + ", " + + "url=" + url + ", " + + "name=" + name + ']'; } - return torrentList.toArray(new Pair[0]); } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java index 04afe1f6e..35eb445d2 100755 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java @@ -86,6 +86,7 @@ import com.hippo.ehviewer.client.data.PreviewSet; import com.hippo.ehviewer.client.exception.NoHAtHClientException; import com.hippo.ehviewer.client.parser.ArchiveParser; import com.hippo.ehviewer.client.parser.RateGalleryParser; +import com.hippo.ehviewer.client.parser.TorrentParser; import com.hippo.ehviewer.client.parser.VoteTagParser; import com.hippo.ehviewer.dao.DownloadInfo; import com.hippo.ehviewer.dao.Filter; @@ -243,7 +244,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O @Nullable private GalleryDetail mGalleryDetail; private int mRequestId = IntIdGenerator.INVALID_ID; - private Pair[] mTorrentList; + private List mTorrentList; ActivityResultLauncher requestStoragePermissionLauncher = registerForActivityResult( new ActivityResultContracts.RequestPermission(), result -> { @@ -1879,7 +1880,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O } private class TorrentListDialogHelper implements AdapterView.OnItemClickListener, - DialogInterface.OnDismissListener, EhClient.Callback[]> { + DialogInterface.OnDismissListener, EhClient.Callback> { @Nullable private CircularProgressIndicator mProgressView; @@ -1914,21 +1915,18 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O } } - private void bind(Pair[] data) { + private void bind(List data) { if (null == mDialog || null == mProgressView || null == mErrorText || null == mListView) { return; } - if (0 == data.length) { + if (null == data || 0 == data.size()) { mProgressView.setVisibility(View.GONE); mErrorText.setVisibility(View.VISIBLE); mListView.setVisibility(View.GONE); mErrorText.setText(R.string.no_torrents); } else { - String[] nameArray = new String[data.length]; - for (int i = 0, n = data.length; i < n; i++) { - nameArray[i] = data[i].second; - } + var nameArray = data.stream().map(torrent -> torrent.format(getResources()::getString)).toArray(String[]::new); mProgressView.setVisibility(View.GONE); mErrorText.setVisibility(View.GONE); mListView.setVisibility(View.VISIBLE); @@ -1939,9 +1937,9 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O @Override public void onItemClick(AdapterView parent, View view, int position, long id) { Context context = getContext(); - if (null != context && null != mTorrentList && position < mTorrentList.length) { - String url = mTorrentList[position].first; - String name = mTorrentList[position].second; + if (null != context && null != mTorrentList && position < mTorrentList.size()) { + String url = mTorrentList.get(position).url(); + String name = mTorrentList.get(position).name(); // TODO: Don't use buggy system download service DownloadManager.Request r = new DownloadManager.Request(Uri.parse(url.replace("exhentai.org", "ehtracker.org"))); r.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, @@ -1979,7 +1977,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O } @Override - public void onSuccess(Pair[] result) { + public void onSuccess(List result) { if (mRequest != null) { mRequest = null; mTorrentList = result; diff --git a/app/src/main/res/layout/item_select_dialog.xml b/app/src/main/res/layout/item_select_dialog.xml index 7ed236835..8d1aeffc2 100644 --- a/app/src/main/res/layout/item_select_dialog.xml +++ b/app/src/main/res/layout/item_select_dialog.xml @@ -23,4 +23,5 @@ android:gravity="center_vertical" android:minHeight="?attr/listPreferredItemHeightSmall" android:paddingLeft="?attr/listPreferredItemPaddingLeft" - android:paddingRight="?attr/listPreferredItemPaddingRight" /> + android:paddingRight="?attr/listPreferredItemPaddingRight" + android:paddingVertical="6dp" />