summaryrefslogtreecommitdiff
path: root/core/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilterGroup.java37
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/SubscriptionsFilterGroup.java33
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/menuhandler/MenuItemUtils.java28
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java21
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/ChapterMerger.java (renamed from core/src/main/java/de/danoeh/antennapod/core/feed/ChapterMerger.java)2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/ConfirmationDialog.java (renamed from core/src/main/java/de/danoeh/antennapod/core/dialog/ConfirmationDialog.java)2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/DownloadErrorLabel.java46
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/PowerUtils.java30
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java91
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/download/MediaSizeLoader.java78
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/download/NetworkConnectionChangeHandler.java29
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/gui/MoreContentListFooterUtil.java53
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/gui/PictureInPictureUtil.java27
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/gui/ShownotesCleaner.java208
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/syndication/FeedDiscoverer.java79
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java123
17 files changed, 20 insertions, 868 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilterGroup.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilterGroup.java
deleted file mode 100644
index fbdf6b3a9..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItemFilterGroup.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package de.danoeh.antennapod.core.feed;
-
-import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.model.feed.FeedItemFilter;
-
-public enum FeedItemFilterGroup {
- PLAYED(new ItemProperties(R.string.hide_played_episodes_label, FeedItemFilter.PLAYED),
- new ItemProperties(R.string.not_played, FeedItemFilter.UNPLAYED)),
- PAUSED(new ItemProperties(R.string.hide_paused_episodes_label, FeedItemFilter.PAUSED),
- new ItemProperties(R.string.not_paused, FeedItemFilter.NOT_PAUSED)),
- FAVORITE(new ItemProperties(R.string.hide_is_favorite_label, FeedItemFilter.IS_FAVORITE),
- new ItemProperties(R.string.not_favorite, FeedItemFilter.NOT_FAVORITE)),
- MEDIA(new ItemProperties(R.string.has_media, FeedItemFilter.HAS_MEDIA),
- new ItemProperties(R.string.no_media, FeedItemFilter.NO_MEDIA)),
- QUEUED(new ItemProperties(R.string.queued_label, FeedItemFilter.QUEUED),
- new ItemProperties(R.string.not_queued_label, FeedItemFilter.NOT_QUEUED)),
- DOWNLOADED(new ItemProperties(R.string.hide_downloaded_episodes_label, FeedItemFilter.DOWNLOADED),
- new ItemProperties(R.string.hide_not_downloaded_episodes_label, FeedItemFilter.NOT_DOWNLOADED));
-
- public final ItemProperties[] values;
-
- FeedItemFilterGroup(ItemProperties... values) {
- this.values = values;
- }
-
- public static class ItemProperties {
-
- public final int displayName;
- public final String filterId;
-
- public ItemProperties(int displayName, String filterId) {
- this.displayName = displayName;
- this.filterId = filterId;
- }
-
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/SubscriptionsFilterGroup.java b/core/src/main/java/de/danoeh/antennapod/core/feed/SubscriptionsFilterGroup.java
deleted file mode 100644
index cea5d96ef..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/SubscriptionsFilterGroup.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package de.danoeh.antennapod.core.feed;
-
-import de.danoeh.antennapod.core.R;
-
-public enum SubscriptionsFilterGroup {
- COUNTER_GREATER_ZERO(new ItemProperties(R.string.subscriptions_counter_greater_zero, "counter_greater_zero")),
- AUTO_DOWNLOAD(new ItemProperties(R.string.auto_downloaded, "enabled_auto_download"),
- new ItemProperties(R.string.not_auto_downloaded, "disabled_auto_download")),
- UPDATED(new ItemProperties(R.string.kept_updated, "enabled_updates"),
- new ItemProperties(R.string.not_kept_updated, "disabled_updates")),
- NEW_EPISODE_NOTIFICATION(new ItemProperties(R.string.new_episode_notification_enabled,
- "episode_notification_enabled"),
- new ItemProperties(R.string.new_episode_notification_disabled, "episode_notification_disabled"));
-
-
- public final ItemProperties[] values;
-
- SubscriptionsFilterGroup(ItemProperties... values) {
- this.values = values;
- }
-
- public static class ItemProperties {
-
- public final int displayName;
- public final String filterId;
-
- public ItemProperties(int displayName, String filterId) {
- this.displayName = displayName;
- this.filterId = filterId;
- }
-
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/menuhandler/MenuItemUtils.java b/core/src/main/java/de/danoeh/antennapod/core/menuhandler/MenuItemUtils.java
deleted file mode 100644
index 829add126..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/menuhandler/MenuItemUtils.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package de.danoeh.antennapod.core.menuhandler;
-
-import android.view.Menu;
-import android.view.MenuItem;
-
-/**
- * Utilities for menu items
- */
-public class MenuItemUtils {
-
- /**
- * When pressing a context menu item, Android calls onContextItemSelected
- * for ALL fragments in arbitrary order, not just for the fragment that the
- * context menu was created from. This assigns the listener to every menu item,
- * so that the correct fragment is always called first and can consume the click.
- * <p />
- * Note that Android still calls the onContextItemSelected methods of all fragments
- * when the passed listener returns false.
- */
- public static void setOnClickListeners(Menu menu, MenuItem.OnMenuItemClickListener listener) {
- for (int i = 0; i < menu.size(); i++) {
- if (menu.getItem(i).getSubMenu() != null) {
- setOnClickListeners(menu.getItem(i).getSubMenu(), listener);
- }
- menu.getItem(i).setOnMenuItemClickListener(listener);
- }
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java b/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java
index 93f7d578a..dbcc899ba 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/AutomaticDownloadAlgorithm.java
@@ -1,6 +1,9 @@
package de.danoeh.antennapod.core.storage;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
import android.util.Log;
import java.util.ArrayList;
@@ -15,7 +18,6 @@ import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterfa
import de.danoeh.antennapod.storage.database.DBReader;
import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.net.common.NetworkUtils;
-import de.danoeh.antennapod.core.util.PowerUtils;
/**
* Implements the automatic download algorithm used by AntennaPod. This class assumes that
@@ -42,8 +44,7 @@ public class AutomaticDownloadAlgorithm {
&& UserPreferences.isEnableAutodownload();
// true if we should auto download based on power status
- boolean powerShouldAutoDl = PowerUtils.deviceCharging(context)
- || UserPreferences.isEnableAutodownloadOnBattery();
+ boolean powerShouldAutoDl = deviceCharging(context) || UserPreferences.isEnableAutodownloadOnBattery();
// we should only auto download if both network AND power are happy
if (networkShouldAutoDl && powerShouldAutoDl) {
@@ -103,4 +104,18 @@ public class AutomaticDownloadAlgorithm {
}
};
}
+
+ /**
+ * @return true if the device is charging
+ */
+ public static boolean deviceCharging(Context context) {
+ // from http://developer.android.com/training/monitoring-device-state/battery-monitoring.html
+ IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+ Intent batteryStatus = context.registerReceiver(null, intentFilter);
+
+ int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
+ return (status == BatteryManager.BATTERY_STATUS_CHARGING
+ || status == BatteryManager.BATTERY_STATUS_FULL);
+
+ }
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/ChapterMerger.java b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterMerger.java
index 9bbab7251..794b2322d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/ChapterMerger.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterMerger.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.core.feed;
+package de.danoeh.antennapod.core.util;
import android.text.TextUtils;
import android.util.Log;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java
index 1af81802b..b32b05236 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java
@@ -7,7 +7,6 @@ import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import de.danoeh.antennapod.model.feed.Chapter;
-import de.danoeh.antennapod.core.feed.ChapterMerger;
import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.net.common.AntennapodHttpClient;
import de.danoeh.antennapod.storage.database.DBReader;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/dialog/ConfirmationDialog.java b/core/src/main/java/de/danoeh/antennapod/core/util/ConfirmationDialog.java
index b964c7508..ff5e56f5d 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/dialog/ConfirmationDialog.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/ConfirmationDialog.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.core.dialog;
+package de.danoeh.antennapod.core.util;
import android.content.Context;
import android.content.DialogInterface;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/DownloadErrorLabel.java b/core/src/main/java/de/danoeh/antennapod/core/util/DownloadErrorLabel.java
deleted file mode 100644
index 3d2558a9f..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/DownloadErrorLabel.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package de.danoeh.antennapod.core.util;
-
-import androidx.annotation.StringRes;
-import de.danoeh.antennapod.core.BuildConfig;
-import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.model.download.DownloadError;
-
-/**
- * Provides user-visible labels for download errors.
- */
-public class DownloadErrorLabel {
-
- @StringRes
- public static int from(DownloadError error) {
- switch (error) {
- case SUCCESS: return R.string.download_successful;
- case ERROR_PARSER_EXCEPTION: return R.string.download_error_parser_exception;
- case ERROR_UNSUPPORTED_TYPE: return R.string.download_error_unsupported_type;
- case ERROR_CONNECTION_ERROR: return R.string.download_error_connection_error;
- case ERROR_MALFORMED_URL: return R.string.download_error_error_unknown;
- case ERROR_IO_ERROR: return R.string.download_error_io_error;
- case ERROR_FILE_EXISTS: return R.string.download_error_error_unknown;
- case ERROR_DOWNLOAD_CANCELLED: return R.string.download_canceled_msg;
- case ERROR_DEVICE_NOT_FOUND: return R.string.download_error_device_not_found;
- case ERROR_HTTP_DATA_ERROR: return R.string.download_error_http_data_error;
- case ERROR_NOT_ENOUGH_SPACE: return R.string.download_error_insufficient_space;
- case ERROR_UNKNOWN_HOST: return R.string.download_error_unknown_host;
- case ERROR_REQUEST_ERROR: return R.string.download_error_request_error;
- case ERROR_DB_ACCESS_ERROR: return R.string.download_error_db_access;
- case ERROR_UNAUTHORIZED: return R.string.download_error_unauthorized;
- case ERROR_FILE_TYPE: return R.string.download_error_file_type_type;
- case ERROR_FORBIDDEN: return R.string.download_error_forbidden;
- case ERROR_IO_WRONG_SIZE: return R.string.download_error_wrong_size;
- case ERROR_IO_BLOCKED: return R.string.download_error_blocked;
- case ERROR_UNSUPPORTED_TYPE_HTML: return R.string.download_error_unsupported_type_html;
- case ERROR_NOT_FOUND: return R.string.download_error_not_found;
- case ERROR_CERTIFICATE: return R.string.download_error_certificate;
- case ERROR_PARSER_EXCEPTION_DUPLICATE: return R.string.download_error_parser_exception;
- default:
- if (BuildConfig.DEBUG) {
- throw new IllegalArgumentException("No mapping from download error to label");
- }
- return R.string.download_error_error_unknown;
- }
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/PowerUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/PowerUtils.java
deleted file mode 100644
index a1fadb4dc..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/PowerUtils.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package de.danoeh.antennapod.core.util;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.BatteryManager;
-
-/**
- * Created by Tom on 1/5/15.
- */
-public class PowerUtils {
-
- private PowerUtils() {
-
- }
-
- /**
- * @return true if the device is charging
- */
- public static boolean deviceCharging(Context context) {
- // from http://developer.android.com/training/monitoring-device-state/battery-monitoring.html
- IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
- Intent batteryStatus = context.registerReceiver(null, iFilter);
-
- int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
- return (status == BatteryManager.BATTERY_STATUS_CHARGING ||
- status == BatteryManager.BATTERY_STATUS_FULL);
-
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java
deleted file mode 100644
index 316771123..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/ShareUtils.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package de.danoeh.antennapod.core.util;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.core.app.ShareCompat;
-import androidx.core.content.FileProvider;
-
-import de.danoeh.antennapod.ui.common.Converter;
-import java.io.File;
-import java.net.URLEncoder;
-
-import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.model.feed.Feed;
-import de.danoeh.antennapod.model.feed.FeedItem;
-import de.danoeh.antennapod.model.feed.FeedMedia;
-
-/** Utility methods for sharing data */
-public class ShareUtils {
- private static final String TAG = "ShareUtils";
-
- private ShareUtils() {
- }
-
- public static void shareLink(@NonNull Context context, @NonNull String text) {
- Intent intent = new ShareCompat.IntentBuilder(context)
- .setType("text/plain")
- .setText(text)
- .setChooserTitle(R.string.share_url_label)
- .createChooserIntent();
- context.startActivity(intent);
- }
-
- public static void shareFeedLink(Context context, Feed feed) {
- String text = feed.getTitle()
- + "\n\n"
- + "https://antennapod.org/deeplink/subscribe/?url="
- + URLEncoder.encode(feed.getDownloadUrl())
- + "&title="
- + URLEncoder.encode(feed.getTitle());
- shareLink(context, text);
- }
-
- public static boolean hasLinkToShare(FeedItem item) {
- return FeedItemUtil.getLinkWithFallback(item) != null;
- }
-
- public static void shareMediaDownloadLink(Context context, FeedMedia media) {
- shareLink(context, media.getDownloadUrl());
- }
-
- public static void shareFeedItemLinkWithDownloadLink(Context context, FeedItem item, boolean withPosition) {
- String text = item.getFeed().getTitle() + ": " + item.getTitle();
- int pos = 0;
- if (item.getMedia() != null && withPosition) {
- text += "\n" + context.getResources().getString(R.string.share_starting_position_label) + ": ";
- pos = item.getMedia().getPosition();
- text += Converter.getDurationStringLong(pos);
- }
-
- if (hasLinkToShare(item)) {
- text += "\n\n" + context.getResources().getString(R.string.share_dialog_episode_website_label) + ": ";
- text += FeedItemUtil.getLinkWithFallback(item);
- }
-
- if (item.getMedia() != null && item.getMedia().getDownloadUrl() != null) {
- text += "\n\n" + context.getResources().getString(R.string.share_dialog_media_file_label) + ": ";
- text += item.getMedia().getDownloadUrl();
- if (withPosition) {
- text += "#t=" + pos / 1000;
- }
- }
- shareLink(context, text);
- }
-
- public static void shareFeedItemFile(Context context, FeedMedia media) {
- Uri fileUri = FileProvider.getUriForFile(context, context.getString(R.string.provider_authority),
- new File(media.getLocalFileUrl()));
-
- new ShareCompat.IntentBuilder(context)
- .setType(media.getMimeType())
- .addStream(fileUri)
- .setChooserTitle(R.string.share_file_label)
- .startChooser();
-
- Log.e(TAG, "shareFeedItemFile called");
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/download/MediaSizeLoader.java b/core/src/main/java/de/danoeh/antennapod/core/util/download/MediaSizeLoader.java
deleted file mode 100644
index 779f3b947..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/download/MediaSizeLoader.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package de.danoeh.antennapod.core.util.download;
-
-import android.text.TextUtils;
-import de.danoeh.antennapod.net.common.AntennapodHttpClient;
-import de.danoeh.antennapod.storage.database.DBWriter;
-import de.danoeh.antennapod.net.common.NetworkUtils;
-import de.danoeh.antennapod.model.feed.FeedMedia;
-import io.reactivex.Single;
-import io.reactivex.SingleOnSubscribe;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.schedulers.Schedulers;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import android.util.Log;
-import okhttp3.Response;
-
-import java.io.File;
-import java.io.IOException;
-
-public abstract class MediaSizeLoader {
- private static final String TAG = "MediaSizeLoader";
-
- public static Single<Long> getFeedMediaSizeObservable(FeedMedia media) {
- return Single.create((SingleOnSubscribe<Long>) emitter -> {
- if (!NetworkUtils.isEpisodeHeadDownloadAllowed()) {
- emitter.onSuccess(0L);
- return;
- }
- long size = Integer.MIN_VALUE;
- if (media.isDownloaded()) {
- File mediaFile = new File(media.getLocalFileUrl());
- if (mediaFile.exists()) {
- size = mediaFile.length();
- }
- } else if (!media.checkedOnSizeButUnknown()) {
- // only query the network if we haven't already checked
-
- String url = media.getDownloadUrl();
- if (TextUtils.isEmpty(url)) {
- emitter.onSuccess(0L);
- return;
- }
-
- OkHttpClient client = AntennapodHttpClient.getHttpClient();
- Request.Builder httpReq = new Request.Builder()
- .url(url)
- .header("Accept-Encoding", "identity")
- .head();
- try {
- Response response = client.newCall(httpReq.build()).execute();
- if (response.isSuccessful()) {
- String contentLength = response.header("Content-Length");
- try {
- size = Integer.parseInt(contentLength);
- } catch (NumberFormatException e) {
- Log.e(TAG, Log.getStackTraceString(e));
- }
- }
- } catch (IOException e) {
- emitter.onSuccess(0L);
- Log.e(TAG, Log.getStackTraceString(e));
- return; // better luck next time
- }
- }
- Log.d(TAG, "new size: " + size);
- if (size <= 0) {
- // they didn't tell us the size, but we don't want to keep querying on it
- media.setCheckedOnSizeButUnknown();
- } else {
- media.setSize(size);
- }
- emitter.onSuccess(size);
- DBWriter.setFeedMedia(media);
- })
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread());
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/download/NetworkConnectionChangeHandler.java b/core/src/main/java/de/danoeh/antennapod/core/util/download/NetworkConnectionChangeHandler.java
deleted file mode 100644
index 79c6e76e1..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/download/NetworkConnectionChangeHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package de.danoeh.antennapod.core.util.download;
-
-import android.content.Context;
-import android.util.Log;
-import de.danoeh.antennapod.net.download.serviceinterface.AutoDownloadManager;
-import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterface;
-import de.danoeh.antennapod.net.common.NetworkUtils;
-
-public abstract class NetworkConnectionChangeHandler {
- private static final String TAG = "NetConnChangeHandler";
- private static Context context;
-
- public static void init(Context context) {
- NetworkConnectionChangeHandler.context = context;
- }
-
- public static void networkChangedDetected() {
- if (NetworkUtils.isAutoDownloadAllowed()) {
- Log.d(TAG, "auto-dl network available, starting auto-download");
- AutoDownloadManager.getInstance().autodownloadUndownloadedItems(context);
- } else { // if new network is Wi-Fi, finish ongoing downloads,
- // otherwise cancel all downloads
- if (NetworkUtils.isNetworkRestricted()) {
- Log.i(TAG, "Device is no longer connected to Wi-Fi. Cancelling ongoing downloads");
- DownloadServiceInterface.get().cancelAll(context);
- }
- }
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/gui/MoreContentListFooterUtil.java b/core/src/main/java/de/danoeh/antennapod/core/util/gui/MoreContentListFooterUtil.java
deleted file mode 100644
index 6e5c3e84b..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/gui/MoreContentListFooterUtil.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package de.danoeh.antennapod.core.util.gui;
-
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-
-import de.danoeh.antennapod.core.R;
-
-/**
- * Utility methods for the more_content_list_footer layout.
- */
-public class MoreContentListFooterUtil {
-
- private final View root;
-
- private boolean loading;
-
- private Listener listener;
-
- public MoreContentListFooterUtil(View root) {
- this.root = root;
- root.setOnClickListener(v -> {
- if (listener != null && !loading) {
- listener.onClick();
- }
- });
- }
-
- public void setLoadingState(boolean newState) {
- final ImageView imageView = root.findViewById(R.id.imgExpand);
- final ProgressBar progressBar = root.findViewById(R.id.progBar);
- if (newState) {
- imageView.setVisibility(View.GONE);
- progressBar.setVisibility(View.VISIBLE);
- } else {
- imageView.setVisibility(View.VISIBLE);
- progressBar.setVisibility(View.GONE);
- }
- loading = newState;
- }
-
- public void setClickListener(Listener l) {
- listener = l;
- }
-
- public interface Listener {
- void onClick();
- }
-
- public View getRoot() {
- return root;
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/gui/PictureInPictureUtil.java b/core/src/main/java/de/danoeh/antennapod/core/util/gui/PictureInPictureUtil.java
deleted file mode 100644
index f763653a1..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/gui/PictureInPictureUtil.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.danoeh.antennapod.core.util.gui;
-
-import android.app.Activity;
-import android.content.pm.PackageManager;
-import android.os.Build;
-
-public class PictureInPictureUtil {
- private PictureInPictureUtil() {
- }
-
- public static boolean supportsPictureInPicture(Activity activity) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- PackageManager packageManager = activity.getPackageManager();
- return packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
- } else {
- return false;
- }
- }
-
- public static boolean isInPictureInPictureMode(Activity activity) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && supportsPictureInPicture(activity)) {
- return activity.isInPictureInPictureMode();
- } else {
- return false;
- }
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/gui/ShownotesCleaner.java b/core/src/main/java/de/danoeh/antennapod/core/util/gui/ShownotesCleaner.java
deleted file mode 100644
index 7bf9257a1..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/gui/ShownotesCleaner.java
+++ /dev/null
@@ -1,208 +0,0 @@
-package de.danoeh.antennapod.core.util.gui;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import androidx.annotation.ColorInt;
-import androidx.annotation.NonNull;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.TypedValue;
-
-import androidx.annotation.Nullable;
-import org.apache.commons.io.IOUtils;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import de.danoeh.antennapod.core.R;
-import de.danoeh.antennapod.ui.common.Converter;
-
-/**
- * Cleans up and prepares shownotes:
- * - Guesses time stamps to make them clickable
- * - Removes some formatting
- */
-public class ShownotesCleaner {
- private static final String TAG = "Timeline";
-
- private static final Pattern TIMECODE_LINK_REGEX = Pattern.compile("antennapod://timecode/(\\d+)");
- private static final String TIMECODE_LINK = "<a class=\"timecode\" href=\"antennapod://timecode/%d\">%s</a>";
- private static final Pattern TIMECODE_REGEX = Pattern.compile("\\b((\\d+):)?(\\d+):(\\d{2})\\b");
- private static final Pattern LINE_BREAK_REGEX = Pattern.compile("<br */?>");
- private static final String CSS_COLOR = "(?<=(\\s|;|^))color\\s*:([^;])*;";
- private static final String CSS_COMMENT = "/\\*.*?\\*/";
-
- private final String rawShownotes;
- private final String noShownotesLabel;
- private final int playableDuration;
- private final String webviewStyle;
-
- public ShownotesCleaner(Context context, @Nullable String rawShownotes, int playableDuration) {
- this.rawShownotes = rawShownotes;
-
- noShownotesLabel = context.getString(R.string.no_shownotes_label);
- this.playableDuration = playableDuration;
- final String colorPrimary = colorToHtml(context, android.R.attr.textColorPrimary);
- final String colorAccent = colorToHtml(context, R.attr.colorAccent);
- final int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,
- context.getResources().getDisplayMetrics());
- String styleString = "";
- try {
- InputStream templateStream = context.getAssets().open("shownotes-style.css");
- styleString = IOUtils.toString(templateStream, "UTF-8");
- } catch (IOException e) {
- e.printStackTrace();
- }
- webviewStyle = String.format(Locale.US, styleString, colorPrimary, colorAccent,
- margin, margin, margin, margin);
- }
-
- private String colorToHtml(Context context, int colorAttr) {
- TypedArray res = context.getTheme().obtainStyledAttributes(new int[]{colorAttr});
- @ColorInt int col = res.getColor(0, 0);
- final String color = "rgba(" + Color.red(col) + "," + Color.green(col) + ","
- + Color.blue(col) + "," + (Color.alpha(col) / 255.0) + ")";
- res.recycle();
- return color;
- }
-
- /**
- * Applies an app-specific CSS stylesheet and adds timecode links (optional).
- * <p/>
- * This method does NOT change the original shownotes string of the shownotesProvider object and it should
- * also not be changed by the caller.
- *
- * @return The processed HTML string.
- */
- @NonNull
- public String processShownotes() {
- String shownotes = rawShownotes;
-
- if (TextUtils.isEmpty(shownotes)) {
- Log.d(TAG, "shownotesProvider contained no shownotes. Returning 'no shownotes' message");
- shownotes = "<html><head></head><body><p id='apNoShownotes'>" + noShownotesLabel + "</p></body></html>";
- }
-
- // replace ASCII line breaks with HTML ones if shownotes don't contain HTML line breaks already
- if (!LINE_BREAK_REGEX.matcher(shownotes).find() && !shownotes.contains("<p>")) {
- shownotes = shownotes.replace("\n", "<br />");
- }
-
- Document document = Jsoup.parse(shownotes);
- cleanCss(document);
- document.head().appendElement("style").attr("type", "text/css").text(webviewStyle);
- addTimecodes(document);
- return document.toString();
- }
-
- /**
- * Returns true if the given link is a timecode link.
- */
- public static boolean isTimecodeLink(String link) {
- return link != null && link.matches(TIMECODE_LINK_REGEX.pattern());
- }
-
- /**
- * Returns the time in milliseconds that is attached to this link or -1
- * if the link is no valid timecode link.
- */
- public static int getTimecodeLinkTime(String link) {
- if (isTimecodeLink(link)) {
- Matcher m = TIMECODE_LINK_REGEX.matcher(link);
-
- try {
- if (m.find()) {
- return Integer.parseInt(m.group(1));
- }
- } catch (NumberFormatException e) {
- e.printStackTrace();
- }
- }
- return -1;
- }
-
- private void addTimecodes(Document document) {
- Elements elementsWithTimeCodes = document.body().getElementsMatchingOwnText(TIMECODE_REGEX);
- Log.d(TAG, "Recognized " + elementsWithTimeCodes.size() + " timecodes");
-
- if (elementsWithTimeCodes.size() == 0) {
- // No elements with timecodes
- return;
- }
- boolean useHourFormat = true;
-
- if (playableDuration != Integer.MAX_VALUE) {
-
- // We need to decide if we are going to treat short timecodes as HH:MM or MM:SS. To do
- // so we will parse all the short timecodes and see if they fit in the duration. If one
- // does not we will use MM:SS, otherwise all will be parsed as HH:MM.
- for (Element element : elementsWithTimeCodes) {
- Matcher matcherForElement = TIMECODE_REGEX.matcher(element.html());
- while (matcherForElement.find()) {
-
- // We only want short timecodes right now.
- if (matcherForElement.group(1) == null) {
- int time = Converter.durationStringShortToMs(matcherForElement.group(0), true);
-
- // If the parsed timecode is greater then the duration then we know we need to
- // use the minute format so we are done.
- if (time > playableDuration) {
- useHourFormat = false;
- break;
- }
- }
- }
-
- if (!useHourFormat) {
- break;
- }
- }
- }
-
- for (Element element : elementsWithTimeCodes) {
-
- Matcher matcherForElement = TIMECODE_REGEX.matcher(element.html());
- StringBuffer buffer = new StringBuffer();
-
- while (matcherForElement.find()) {
- String group = matcherForElement.group(0);
-
- int time = matcherForElement.group(1) != null
- ? Converter.durationStringLongToMs(group)
- : Converter.durationStringShortToMs(group, useHourFormat);
-
- String replacementText = group;
- if (time < playableDuration) {
- replacementText = String.format(Locale.US, TIMECODE_LINK, time, group);
- }
-
- matcherForElement.appendReplacement(buffer, replacementText);
- }
-
- matcherForElement.appendTail(buffer);
- element.html(buffer.toString());
- }
- }
-
- private void cleanCss(Document document) {
- for (Element element : document.getAllElements()) {
- if (element.hasAttr("style")) {
- element.attr("style", element.attr("style").replaceAll(CSS_COLOR, ""));
- } else if (element.tagName().equals("style")) {
- element.html(cleanStyleTag(element.html()));
- }
- }
- }
-
- public static String cleanStyleTag(String oldCss) {
- return oldCss.replaceAll(CSS_COMMENT, "").replaceAll(CSS_COLOR, "");
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/syndication/FeedDiscoverer.java b/core/src/main/java/de/danoeh/antennapod/core/util/syndication/FeedDiscoverer.java
deleted file mode 100644
index 316608f2f..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/syndication/FeedDiscoverer.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package de.danoeh.antennapod.core.util.syndication;
-
-import android.net.Uri;
-import androidx.collection.ArrayMap;
-import android.text.TextUtils;
-
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * Finds RSS/Atom URLs in a HTML document using the auto-discovery techniques described here:
- * <p/>
- * http://www.rssboard.org/rss-autodiscovery
- * <p/>
- * http://blog.whatwg.org/feed-autodiscovery
- */
-public class FeedDiscoverer {
-
- private static final String MIME_RSS = "application/rss+xml";
- private static final String MIME_ATOM = "application/atom+xml";
-
- /**
- * Discovers links to RSS and Atom feeds in the given File which must be a HTML document.
- *
- * @return A map which contains the feed URLs as keys and titles as values (the feed URL is also used as a title if
- * a title cannot be found).
- */
- public Map<String, String> findLinks(File in, String baseUrl) throws IOException {
- return findLinks(Jsoup.parse(in), baseUrl);
- }
-
- /**
- * Discovers links to RSS and Atom feeds in the given File which must be a HTML document.
- *
- * @return A map which contains the feed URLs as keys and titles as values (the feed URL is also used as a title if
- * a title cannot be found).
- */
- public Map<String, String> findLinks(String in, String baseUrl) {
- return findLinks(Jsoup.parse(in), baseUrl);
- }
-
- private Map<String, String> findLinks(Document document, String baseUrl) {
- Map<String, String> res = new ArrayMap<>();
- Elements links = document.head().getElementsByTag("link");
- for (Element link : links) {
- String rel = link.attr("rel");
- String href = link.attr("href");
- if (!TextUtils.isEmpty(href) &&
- (rel.equals("alternate") || rel.equals("feed"))) {
- String type = link.attr("type");
- if (type.equals(MIME_RSS) || type.equals(MIME_ATOM)) {
- String title = link.attr("title");
- String processedUrl = processURL(baseUrl, href);
- if (processedUrl != null) {
- res.put(processedUrl,
- (TextUtils.isEmpty(title)) ? href : title);
- }
- }
- }
- }
- return res;
- }
-
- private String processURL(String baseUrl, String strUrl) {
- Uri uri = Uri.parse(strUrl);
- if (uri.isRelative()) {
- Uri res = Uri.parse(baseUrl).buildUpon().path(strUrl).build();
- return (res != null) ? res.toString() : null;
- } else {
- return strUrl;
- }
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java b/core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java
deleted file mode 100644
index c5f0727c2..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/syndication/HtmlToPlainText.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package de.danoeh.antennapod.core.util.syndication;
-
-import android.text.TextUtils;
-
-import org.apache.commons.lang3.StringUtils;
-import org.jsoup.Jsoup;
-import org.jsoup.internal.StringUtil;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.nodes.Node;
-import org.jsoup.nodes.TextNode;
-import org.jsoup.select.NodeTraversor;
-import org.jsoup.select.NodeVisitor;
-
-import java.util.regex.Pattern;
-
-/**
- * This class is based on <code>HtmlToPlainText</code> from jsoup's examples package.
- *
- * HTML to plain-text. This example program demonstrates the use of jsoup to convert HTML input to lightly-formatted
- * plain-text. That is divergent from the general goal of jsoup's .text() methods, which is to get clean data from a
- * scrape.
- * <p>
- * Note that this is a fairly simplistic formatter -- for real world use you'll want to embrace and extend.
- * </p>
- * <p>
- * To invoke from the command line, assuming you've downloaded the jsoup jar to your current directory:</p>
- * <p><code>java -cp jsoup.jar org.jsoup.examples.HtmlToPlainText url [selector]</code></p>
- * where <i>url</i> is the URL to fetch, and <i>selector</i> is an optional CSS selector.
- *
- * @author Jonathan Hedley, jonathan@hedley.net
- * @author AntennaPod open source community
- */
-public class HtmlToPlainText {
-
- /**
- * Use this method to strip off HTML encoding from given text.
- * Replaces bullet points with *, ignores colors/bold/...
- *
- * @param str String with any encoding
- * @return Human readable text with minimal HTML formatting
- */
- public static String getPlainText(String str) {
- if (!TextUtils.isEmpty(str) && isHtml(str)) {
- HtmlToPlainText formatter = new HtmlToPlainText();
- Document feedDescription = Jsoup.parse(str);
- str = StringUtils.trim(formatter.getPlainText(feedDescription));
- } else if (TextUtils.isEmpty(str)) {
- str = "";
- }
-
- return str;
- }
-
- /**
- * Use this method to determine if a given text has any HTML tag
- *
- * @param str String to be tested for presence of HTML content
- * @return <b>True</b> if text contains any HTML tags<br /><b>False</b> is no HTML tag is found
- */
- private static boolean isHtml(String str) {
- final String htmlTagPattern = "<(\"[^\"]*\"|'[^']*'|[^'\">])*>";
- return Pattern.compile(htmlTagPattern).matcher(str).find();
- }
-
- /**
- * Format an Element to plain-text
- * @param element the root element to format
- * @return formatted text
- */
- public String getPlainText(Element element) {
- FormattingVisitor formatter = new FormattingVisitor();
- // walk the DOM, and call .head() and .tail() for each node
- NodeTraversor.traverse(formatter, element);
-
- return formatter.toString();
- }
-
- // the formatting rules, implemented in a breadth-first DOM traverse
- private static class FormattingVisitor implements NodeVisitor {
-
- private final StringBuilder accum = new StringBuilder(); // holds the accumulated text
-
- // hit when the node is first seen
- public void head(Node node, int depth) {
- String name = node.nodeName();
- if (node instanceof TextNode) {
- append(((TextNode) node).text()); // TextNodes carry all user-readable text in the DOM.
- } else if (name.equals("li")) {
- append("\n * ");
- } else if (name.equals("dt")) {
- append(" ");
- } else if (StringUtil.in(name, "p", "h1", "h2", "h3", "h4", "h5", "tr")) {
- append("\n");
- }
- }
-
- // hit when all of the node's children (if any) have been visited
- public void tail(Node node, int depth) {
- String name = node.nodeName();
- if (StringUtil.in(name, "br", "dd", "dt", "p", "h1", "h2", "h3", "h4", "h5")) {
- append("\n");
- } else if (name.equals("a")) {
- append(String.format(" <%s>", node.absUrl("href")));
- }
- }
-
- // appends text to the string builder with a simple word wrap method
- private void append(String text) {
- if (text.equals(" ") &&
- (accum.length() == 0 || StringUtil.in(accum.substring(accum.length() - 1), " ", "\n"))) {
- return; // don't accumulate long runs of empty spaces
- }
-
- accum.append(text);
- }
-
- @Override
- public String toString() {
- return accum.toString();
- }
- }
-}