Merge pull request #4106 from malockin/export-favorites
Export favourites
This commit is contained in:
commit
e0d1f5d529
|
@ -5,7 +5,6 @@ import android.app.ProgressDialog;
|
|||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
|
@ -25,6 +24,7 @@ import de.danoeh.antennapod.activity.SplashActivity;
|
|||
import de.danoeh.antennapod.asynctask.DocumentFileExportWorker;
|
||||
import de.danoeh.antennapod.asynctask.ExportWorker;
|
||||
import de.danoeh.antennapod.core.export.ExportWriter;
|
||||
import de.danoeh.antennapod.core.export.favorites.FavoritesWriter;
|
||||
import de.danoeh.antennapod.core.export.html.HtmlWriter;
|
||||
import de.danoeh.antennapod.core.export.opml.OpmlWriter;
|
||||
import de.danoeh.antennapod.core.storage.DatabaseExporter;
|
||||
|
@ -47,15 +47,18 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
|
|||
private static final String PREF_HTML_EXPORT = "prefHtmlExport";
|
||||
private static final String PREF_DATABASE_IMPORT = "prefDatabaseImport";
|
||||
private static final String PREF_DATABASE_EXPORT = "prefDatabaseExport";
|
||||
private static final String PREF_FAVORITE_EXPORT = "prefFavoritesExport";
|
||||
private static final String DEFAULT_OPML_OUTPUT_NAME = "antennapod-feeds-%s.opml";
|
||||
private static final String CONTENT_TYPE_OPML = "text/x-opml";
|
||||
private static final String DEFAULT_HTML_OUTPUT_NAME = "antennapod-feeds-%s.html";
|
||||
private static final String CONTENT_TYPE_HTML = "text/html";
|
||||
private static final String DEFAULT_FAVORITES_OUTPUT_NAME = "antennapod-favorites-%s.html";
|
||||
private static final int REQUEST_CODE_CHOOSE_OPML_EXPORT_PATH = 1;
|
||||
private static final int REQUEST_CODE_CHOOSE_OPML_IMPORT_PATH = 2;
|
||||
private static final int REQUEST_CODE_CHOOSE_HTML_EXPORT_PATH = 3;
|
||||
private static final int REQUEST_CODE_RESTORE_DATABASE = 4;
|
||||
private static final int REQUEST_CODE_BACKUP_DATABASE = 5;
|
||||
private static final int REQUEST_CODE_CHOOSE_FAVORITES_EXPORT_PATH = 6;
|
||||
private static final String DATABASE_EXPORT_FILENAME = "AntennaPodBackup-%s.db";
|
||||
private Disposable disposable;
|
||||
private ProgressDialog progressDialog;
|
||||
|
@ -125,6 +128,12 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
|
|||
exportDatabase();
|
||||
return true;
|
||||
});
|
||||
findPreference(PREF_FAVORITE_EXPORT).setOnPreferenceClickListener(
|
||||
preference -> {
|
||||
openExportPathPicker(CONTENT_TYPE_HTML, dateStampFilename(DEFAULT_FAVORITES_OUTPUT_NAME),
|
||||
REQUEST_CODE_CHOOSE_FAVORITES_EXPORT_PATH, new FavoritesWriter());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void exportWithWriter(ExportWriter exportWriter, final Uri uri) {
|
||||
|
@ -257,6 +266,8 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
|
|||
exportWithWriter(new OpmlWriter(), uri);
|
||||
} else if (requestCode == REQUEST_CODE_CHOOSE_HTML_EXPORT_PATH) {
|
||||
exportWithWriter(new HtmlWriter(), uri);
|
||||
} else if (requestCode == REQUEST_CODE_CHOOSE_FAVORITES_EXPORT_PATH) {
|
||||
exportWithWriter(new FavoritesWriter(), uri);
|
||||
} else if (requestCode == REQUEST_CODE_RESTORE_DATABASE) {
|
||||
progressDialog.show();
|
||||
disposable = Completable.fromAction(() -> DatabaseExporter.importBackup(uri, getContext()))
|
||||
|
|
|
@ -32,5 +32,9 @@
|
|||
android:key="prefHtmlExport"
|
||||
android:title="@string/html_export_label"
|
||||
android:summary="@string/html_export_summary"/>
|
||||
<Preference
|
||||
android:key="prefFavoritesExport"
|
||||
android:title="@string/favorites_export_label"
|
||||
android:summary="@string/favorites_export_summary"/>
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<li><span>
|
||||
{FAV_TITLE}<br>
|
||||
<a href="{FAV_WEBSITE}">Website</a> • <a href="{FAV_MEDIA}">Media</a>
|
||||
</span></li>
|
|
@ -0,0 +1,7 @@
|
|||
<img src="{FEED_IMG}" />
|
||||
<p>
|
||||
{FEED_TITLE}
|
||||
<span>
|
||||
<a href="{FEED_LINK}">Website</a> • <a href="{FEED_WEBSITE}">Feed</a>
|
||||
</span>
|
||||
</p>
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version='1.0' encoding='UTF-8' standalone='no' ?>
|
||||
<html>
|
||||
<head>
|
||||
<title>AntennaPod Subscriptions</title>
|
||||
<title>AntennaPod {TITLE}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
* {
|
||||
|
@ -72,11 +72,18 @@
|
|||
margin-top: 10px;
|
||||
clear:left;
|
||||
}
|
||||
ul > li > span {
|
||||
width: 100%;
|
||||
border-top: 1px solid #eee8e8;
|
||||
padding: 5px;
|
||||
box-shadow: none;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src="https://antennapod.org/assets/img/antennapod-logo.png" />
|
||||
<h1>AntennaPod Subscriptions</h1>
|
||||
<h1>AntennaPod {TITLE}</h1>
|
||||
<ul>
|
||||
{FEEDS}
|
||||
</ul>
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
package de.danoeh.antennapod.core.export.favorites;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import de.danoeh.antennapod.core.export.ExportWriter;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
|
||||
/** Writes saved favorites to file. */
|
||||
public class FavoritesWriter implements ExportWriter {
|
||||
private static final String TAG = "FavoritesWriter";
|
||||
|
||||
private static final int PAGE_LIMIT = 100;
|
||||
|
||||
private static final String FAVORITE_TEMPLATE = "html-export-favorites-item-template.html";
|
||||
private static final String FEED_TEMPLATE = "html-export-feed-template.html";
|
||||
private static final String UTF_8 = "UTF-8";
|
||||
|
||||
@Override
|
||||
public void writeDocument(List<Feed> feeds, Writer writer, Context context)
|
||||
throws IllegalArgumentException, IllegalStateException, IOException {
|
||||
Log.d(TAG, "Starting to write document");
|
||||
|
||||
InputStream templateStream = context.getAssets().open("html-export-template.html");
|
||||
String template = IOUtils.toString(templateStream, UTF_8);
|
||||
template = template.replaceAll("\\{TITLE\\}", "Favorites");
|
||||
String[] templateParts = template.split("\\{FEEDS\\}");
|
||||
|
||||
InputStream favTemplateStream = context.getAssets().open(FAVORITE_TEMPLATE);
|
||||
String favTemplate = IOUtils.toString(favTemplateStream, UTF_8);
|
||||
|
||||
InputStream feedTemplateStream = context.getAssets().open(FEED_TEMPLATE);
|
||||
String feedTemplate = IOUtils.toString(feedTemplateStream, UTF_8);
|
||||
|
||||
Map<Long, List<FeedItem>> favoriteByFeed = getFeedMap(getFavorites());
|
||||
|
||||
writer.append(templateParts[0]);
|
||||
|
||||
for (Long feedId : favoriteByFeed.keySet()) {
|
||||
List<FeedItem> favorites = favoriteByFeed.get(feedId);
|
||||
writer.append("<li><div>\n");
|
||||
writeFeed(writer, favorites.get(0).getFeed(), feedTemplate);
|
||||
|
||||
writer.append("<ul>\n");
|
||||
for (FeedItem item : favorites) {
|
||||
writeFavoriteItem(writer, item, favTemplate);
|
||||
}
|
||||
writer.append("</ul></div></li>\n");
|
||||
}
|
||||
|
||||
writer.append(templateParts[1]);
|
||||
|
||||
Log.d(TAG, "Finished writing document");
|
||||
}
|
||||
|
||||
private List<FeedItem> getFavorites() {
|
||||
int page = 0;
|
||||
|
||||
List<FeedItem> favoritesList = new ArrayList<>();
|
||||
List<FeedItem> favoritesPage;
|
||||
do {
|
||||
favoritesPage = DBReader.getFavoriteItemsList(page * PAGE_LIMIT, PAGE_LIMIT);
|
||||
favoritesList.addAll(favoritesPage);
|
||||
++page;
|
||||
} while (!favoritesPage.isEmpty() && favoritesPage.size() == PAGE_LIMIT);
|
||||
|
||||
// sort in descending order
|
||||
Collections.sort(favoritesList, (lhs, rhs) -> rhs.getPubDate().compareTo(lhs.getPubDate()));
|
||||
|
||||
return favoritesList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Group favorite episodes by feed, sorting them by publishing date in descending order.
|
||||
*
|
||||
* @param favoritesList {@code List} of all favorite episodes.
|
||||
* @return A {@code Map} favorite episodes, keyed by feed ID.
|
||||
*/
|
||||
private Map<Long, List<FeedItem>> getFeedMap(List<FeedItem> favoritesList) {
|
||||
Map<Long, List<FeedItem>> feedMap = new TreeMap<>();
|
||||
|
||||
for (FeedItem item : favoritesList) {
|
||||
List<FeedItem> feedEpisodes = feedMap.get(item.getFeedId());
|
||||
|
||||
if (feedEpisodes == null) {
|
||||
feedEpisodes = new ArrayList<>();
|
||||
feedMap.put(item.getFeedId(), feedEpisodes);
|
||||
}
|
||||
|
||||
feedEpisodes.add(item);
|
||||
}
|
||||
|
||||
return feedMap;
|
||||
}
|
||||
|
||||
private void writeFeed(Writer writer, Feed feed, String feedTemplate) throws IOException {
|
||||
String feedInfo = feedTemplate
|
||||
.replace("{FEED_IMG}", feed.getImageUrl())
|
||||
.replace("{FEED_TITLE}", feed.getTitle())
|
||||
.replace("{FEED_LINK}", feed.getLink())
|
||||
.replace("{FEED_WEBSITE}", feed.getDownload_url());
|
||||
|
||||
writer.append(feedInfo);
|
||||
}
|
||||
|
||||
private void writeFavoriteItem(Writer writer, FeedItem item, String favoriteTemplate) throws IOException {
|
||||
String favItem = favoriteTemplate
|
||||
.replace("{FAV_TITLE}", item.getTitle().trim())
|
||||
.replace("{FAV_WEBSITE}", item.getLink())
|
||||
.replace("{FAV_MEDIA}", item.getMedia().getDownload_url());
|
||||
|
||||
writer.append(favItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fileExtension() {
|
||||
return "html";
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ public class HtmlWriter implements ExportWriter {
|
|||
|
||||
InputStream templateStream = context.getAssets().open("html-export-template.html");
|
||||
String template = IOUtils.toString(templateStream, "UTF-8");
|
||||
template = template.replaceAll("\\{TITLE\\}", "Subscriptions");
|
||||
String[] templateParts = template.split("\\{FEEDS\\}");
|
||||
|
||||
writer.append(templateParts[0]);
|
||||
|
|
|
@ -580,6 +580,8 @@
|
|||
<string name="import_select_file">Select file to import</string>
|
||||
<string name="import_ok">Import successful.\n\nPlease press OK to restart AntennaPod</string>
|
||||
<string name="import_no_downgrade">This database was exported with a newer version of AntennaPod. Your current installation does not yet know how to handle this file.</string>
|
||||
<string name="favorites_export_label">Favorites export</string>
|
||||
<string name="favorites_export_summary">Export saved favorites to file</string>
|
||||
|
||||
<!-- Sleep timer -->
|
||||
<string name="set_sleeptimer_label">Set sleep timer</string>
|
||||
|
|
Loading…
Reference in New Issue