Merge pull request #3796 from ByteHamster/html-export-design
Updated html export design
This commit is contained in:
commit
8ed2102c85
|
@ -45,7 +45,7 @@ public class DocumentFileExportWorker {
|
|||
throw new IOException();
|
||||
}
|
||||
writer = new OutputStreamWriter(outputStream, LangUtils.UTF_8);
|
||||
exportWriter.writeDocument(DBReader.getFeedList(), writer);
|
||||
exportWriter.writeDocument(DBReader.getFeedList(), writer, context);
|
||||
subscriber.onNext(output);
|
||||
} catch (IOException e) {
|
||||
subscriber.onError(e);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package de.danoeh.antennapod.asynctask;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -25,15 +26,17 @@ public class ExportWorker {
|
|||
|
||||
private final @NonNull ExportWriter exportWriter;
|
||||
private final @NonNull File output;
|
||||
private final Context context;
|
||||
|
||||
public ExportWorker(@NonNull ExportWriter exportWriter) {
|
||||
public ExportWorker(@NonNull ExportWriter exportWriter, Context context) {
|
||||
this(exportWriter, new File(UserPreferences.getDataFolder(EXPORT_DIR),
|
||||
DEFAULT_OUTPUT_NAME + "." + exportWriter.fileExtension()));
|
||||
DEFAULT_OUTPUT_NAME + "." + exportWriter.fileExtension()), context);
|
||||
}
|
||||
|
||||
private ExportWorker(@NonNull ExportWriter exportWriter, @NonNull File output) {
|
||||
private ExportWorker(@NonNull ExportWriter exportWriter, @NonNull File output, Context context) {
|
||||
this.exportWriter = exportWriter;
|
||||
this.output = output;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public Observable<File> exportObservable() {
|
||||
|
@ -45,7 +48,7 @@ public class ExportWorker {
|
|||
OutputStreamWriter writer = null;
|
||||
try {
|
||||
writer = new OutputStreamWriter(new FileOutputStream(output), LangUtils.UTF_8);
|
||||
exportWriter.writeDocument(DBReader.getFeedList(), writer);
|
||||
exportWriter.writeDocument(DBReader.getFeedList(), writer, context);
|
||||
subscriber.onNext(output);
|
||||
} catch (IOException e) {
|
||||
subscriber.onError(e);
|
||||
|
|
|
@ -171,7 +171,7 @@ public class StoragePreferencesFragment extends PreferenceFragmentCompat {
|
|||
progressDialog.setIndeterminate(true);
|
||||
progressDialog.show();
|
||||
if (uri == null) {
|
||||
Observable<File> observable = new ExportWorker(exportWriter).exportObservable();
|
||||
Observable<File> observable = new ExportWorker(exportWriter, getContext()).exportObservable();
|
||||
disposable = observable.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(output -> {
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<?xml version='1.0' encoding='UTF-8' standalone='no' ?>
|
||||
<html>
|
||||
<head>
|
||||
<title>AntennaPod Subscriptions</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
* {
|
||||
font-family: 'Lato', sans-serif;
|
||||
font-weight: 300;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html {
|
||||
background: #3498db;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
h1 {
|
||||
color: #fff;
|
||||
font-weight: 300;
|
||||
display: inline-block;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 20px;
|
||||
vertical-align: top;
|
||||
}
|
||||
ul {
|
||||
text-align: center;
|
||||
}
|
||||
li {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
display: block;
|
||||
display: inline-flex;
|
||||
padding: 10px;
|
||||
}
|
||||
li > div {
|
||||
background: #fefefe;
|
||||
padding: 10px;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
||||
text-align: left;
|
||||
}
|
||||
li span {
|
||||
margin-top: 10px;
|
||||
display: block;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
span a {
|
||||
color: #3498db;
|
||||
}
|
||||
img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
li > div > img {
|
||||
float: left;
|
||||
}
|
||||
li > div > p {
|
||||
width: 100%;
|
||||
}
|
||||
body > a {
|
||||
color: #ffffff;
|
||||
display: inline-block;
|
||||
margin-top: 10px;
|
||||
clear:left;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src="https://antennapod.org/assets/img/antennapod-logo.png" />
|
||||
<h1>AntennaPod Subscriptions</h1>
|
||||
<ul>
|
||||
{FEEDS}
|
||||
</ul>
|
||||
<a href="https://play.google.com/store/apps/details?id=de.danoeh.antennapod" target="_blank">Get AntennaPod</a>
|
||||
</body>
|
||||
</html>
|
|
@ -93,7 +93,7 @@ public class OpmlBackupAgent extends BackupAgentHelper {
|
|||
|
||||
try {
|
||||
// Write OPML
|
||||
new OpmlWriter().writeDocument(DBReader.getFeedList(), writer);
|
||||
new OpmlWriter().writeDocument(DBReader.getFeedList(), writer, mContext);
|
||||
|
||||
// Compare checksum of new and old file to see if we need to perform a backup at all
|
||||
if (digester != null) {
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package de.danoeh.antennapod.core.export;
|
||||
|
||||
import android.content.Context;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
|
@ -21,9 +23,9 @@ import de.danoeh.antennapod.core.feed.Feed;
|
|||
|
||||
public interface ExportWriter {
|
||||
|
||||
void writeDocument(List<Feed> feeds, Writer writer)
|
||||
throws IllegalArgumentException, IllegalStateException, IOException;
|
||||
void writeDocument(List<Feed> feeds, Writer writer, Context context)
|
||||
throws IllegalArgumentException, IllegalStateException, IOException;
|
||||
|
||||
String fileExtension();
|
||||
String fileExtension();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package de.danoeh.antennapod.core.export.html;
|
||||
|
||||
import de.danoeh.antennapod.core.export.CommonSymbols;
|
||||
|
||||
class HtmlSymbols extends CommonSymbols {
|
||||
|
||||
static final String HTML = "html";
|
||||
|
||||
static final String ORDERED_LIST = "ol";
|
||||
static final String LIST_ITEM = "li";
|
||||
|
||||
static final String HEADING = "h1";
|
||||
|
||||
static final String LINK = "a";
|
||||
static final String LINK_DESTINATION = "href";
|
||||
|
||||
}
|
|
@ -1,77 +1,45 @@
|
|||
package de.danoeh.antennapod.core.export.html;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.core.export.ExportWriter;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
/** Writes HTML documents. */
|
||||
public class HtmlWriter implements ExportWriter {
|
||||
|
||||
private static final String TAG = "HtmlWriter";
|
||||
private static final String ENCODING = "UTF-8";
|
||||
private static final String HTML_TITLE = "AntennaPod Subscriptions";
|
||||
|
||||
/**
|
||||
* Takes a list of feeds and a writer and writes those into an HTML
|
||||
* document.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws IllegalStateException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
@Override
|
||||
public void writeDocument(List<Feed> feeds, Writer writer)
|
||||
public void writeDocument(List<Feed> feeds, Writer writer, Context context)
|
||||
throws IllegalArgumentException, IllegalStateException, IOException {
|
||||
Log.d(TAG, "Starting to write document");
|
||||
XmlSerializer xs = Xml.newSerializer();
|
||||
xs.setFeature(HtmlSymbols.XML_FEATURE_INDENT_OUTPUT, true);
|
||||
xs.setOutput(writer);
|
||||
|
||||
xs.startDocument(ENCODING, false);
|
||||
xs.startTag(null, HtmlSymbols.HTML);
|
||||
xs.startTag(null, HtmlSymbols.HEAD);
|
||||
xs.startTag(null, HtmlSymbols.TITLE);
|
||||
xs.text(HTML_TITLE);
|
||||
xs.endTag(null, HtmlSymbols.TITLE);
|
||||
xs.endTag(null, HtmlSymbols.HEAD);
|
||||
InputStream templateStream = context.getAssets().open("html-export-template.html");
|
||||
String template = IOUtils.toString(templateStream, "UTF-8");
|
||||
String[] templateParts = template.split("\\{FEEDS\\}");
|
||||
|
||||
xs.startTag(null, HtmlSymbols.BODY);
|
||||
xs.startTag(null, HtmlSymbols.HEADING);
|
||||
xs.text(HTML_TITLE);
|
||||
xs.endTag(null, HtmlSymbols.HEADING);
|
||||
xs.startTag(null, HtmlSymbols.ORDERED_LIST);
|
||||
writer.append(templateParts[0]);
|
||||
for (Feed feed : feeds) {
|
||||
xs.startTag(null, HtmlSymbols.LIST_ITEM);
|
||||
xs.text(feed.getTitle());
|
||||
if (!TextUtils.isEmpty(feed.getLink())) {
|
||||
xs.text(" [");
|
||||
xs.startTag(null, HtmlSymbols.LINK);
|
||||
xs.attribute(null, HtmlSymbols.LINK_DESTINATION, feed.getLink());
|
||||
xs.text("Website");
|
||||
xs.endTag(null, HtmlSymbols.LINK);
|
||||
xs.text("]");
|
||||
}
|
||||
xs.text(" [");
|
||||
xs.startTag(null, HtmlSymbols.LINK);
|
||||
xs.attribute(null, HtmlSymbols.LINK_DESTINATION, feed.getDownload_url());
|
||||
xs.text("Feed");
|
||||
xs.endTag(null, HtmlSymbols.LINK);
|
||||
xs.text("]");
|
||||
xs.endTag(null, HtmlSymbols.LIST_ITEM);
|
||||
writer.append("<li><div><img src=\"");
|
||||
writer.append(feed.getImageUrl());
|
||||
writer.append("\" /><p>");
|
||||
writer.append(feed.getTitle());
|
||||
writer.append(" <span><a href=\"");
|
||||
writer.append(feed.getLink());
|
||||
writer.append("\">Website</a> • <a href=\"");
|
||||
writer.append(feed.getDownload_url());
|
||||
writer.append("\">Feed</a></span></p></div></li>\n");
|
||||
}
|
||||
xs.endTag(null, HtmlSymbols.ORDERED_LIST);
|
||||
xs.endTag(null, HtmlSymbols.BODY);
|
||||
xs.endTag(null, HtmlSymbols.HTML);
|
||||
xs.endDocument();
|
||||
writer.append(templateParts[1]);
|
||||
Log.d(TAG, "Finished writing document");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package de.danoeh.antennapod.core.export.opml;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
|
@ -17,62 +18,58 @@ import de.danoeh.antennapod.core.util.DateUtils;
|
|||
/** Writes OPML documents. */
|
||||
public class OpmlWriter implements ExportWriter {
|
||||
|
||||
private static final String TAG = "OpmlWriter";
|
||||
private static final String ENCODING = "UTF-8";
|
||||
private static final String OPML_VERSION = "2.0";
|
||||
private static final String OPML_TITLE = "AntennaPod Subscriptions";
|
||||
private static final String TAG = "OpmlWriter";
|
||||
private static final String ENCODING = "UTF-8";
|
||||
private static final String OPML_VERSION = "2.0";
|
||||
private static final String OPML_TITLE = "AntennaPod Subscriptions";
|
||||
|
||||
/**
|
||||
* Takes a list of feeds and a writer and writes those into an OPML
|
||||
* document.
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws IllegalStateException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
@Override
|
||||
public void writeDocument(List<Feed> feeds, Writer writer)
|
||||
throws IllegalArgumentException, IllegalStateException, IOException {
|
||||
Log.d(TAG, "Starting to write document");
|
||||
XmlSerializer xs = Xml.newSerializer();
|
||||
xs.setFeature(OpmlSymbols.XML_FEATURE_INDENT_OUTPUT, true);
|
||||
xs.setOutput(writer);
|
||||
/**
|
||||
* Takes a list of feeds and a writer and writes those into an OPML
|
||||
* document.
|
||||
*/
|
||||
@Override
|
||||
public void writeDocument(List<Feed> feeds, Writer writer, Context context)
|
||||
throws IllegalArgumentException, IllegalStateException, IOException {
|
||||
Log.d(TAG, "Starting to write document");
|
||||
XmlSerializer xs = Xml.newSerializer();
|
||||
xs.setFeature(OpmlSymbols.XML_FEATURE_INDENT_OUTPUT, true);
|
||||
xs.setOutput(writer);
|
||||
|
||||
xs.startDocument(ENCODING, false);
|
||||
xs.startTag(null, OpmlSymbols.OPML);
|
||||
xs.attribute(null, OpmlSymbols.VERSION, OPML_VERSION);
|
||||
xs.startDocument(ENCODING, false);
|
||||
xs.startTag(null, OpmlSymbols.OPML);
|
||||
xs.attribute(null, OpmlSymbols.VERSION, OPML_VERSION);
|
||||
|
||||
xs.startTag(null, OpmlSymbols.HEAD);
|
||||
xs.startTag(null, OpmlSymbols.TITLE);
|
||||
xs.text(OPML_TITLE);
|
||||
xs.endTag(null, OpmlSymbols.TITLE);
|
||||
xs.startTag(null, OpmlSymbols.DATE_CREATED);
|
||||
xs.text(DateUtils.formatRFC822Date(new Date()));
|
||||
xs.endTag(null, OpmlSymbols.DATE_CREATED);
|
||||
xs.endTag(null, OpmlSymbols.HEAD);
|
||||
xs.startTag(null, OpmlSymbols.HEAD);
|
||||
xs.startTag(null, OpmlSymbols.TITLE);
|
||||
xs.text(OPML_TITLE);
|
||||
xs.endTag(null, OpmlSymbols.TITLE);
|
||||
xs.startTag(null, OpmlSymbols.DATE_CREATED);
|
||||
xs.text(DateUtils.formatRFC822Date(new Date()));
|
||||
xs.endTag(null, OpmlSymbols.DATE_CREATED);
|
||||
xs.endTag(null, OpmlSymbols.HEAD);
|
||||
|
||||
xs.startTag(null, OpmlSymbols.BODY);
|
||||
for (Feed feed : feeds) {
|
||||
xs.startTag(null, OpmlSymbols.OUTLINE);
|
||||
xs.attribute(null, OpmlSymbols.TEXT, feed.getTitle());
|
||||
xs.attribute(null, OpmlSymbols.TITLE, feed.getTitle());
|
||||
if (feed.getType() != null) {
|
||||
xs.attribute(null, OpmlSymbols.TYPE, feed.getType());
|
||||
}
|
||||
xs.attribute(null, OpmlSymbols.XMLURL, feed.getDownload_url());
|
||||
if (feed.getLink() != null) {
|
||||
xs.attribute(null, OpmlSymbols.HTMLURL, feed.getLink());
|
||||
}
|
||||
xs.endTag(null, OpmlSymbols.OUTLINE);
|
||||
}
|
||||
xs.endTag(null, OpmlSymbols.BODY);
|
||||
xs.endTag(null, OpmlSymbols.OPML);
|
||||
xs.endDocument();
|
||||
Log.d(TAG, "Finished writing document");
|
||||
}
|
||||
xs.startTag(null, OpmlSymbols.BODY);
|
||||
for (Feed feed : feeds) {
|
||||
xs.startTag(null, OpmlSymbols.OUTLINE);
|
||||
xs.attribute(null, OpmlSymbols.TEXT, feed.getTitle());
|
||||
xs.attribute(null, OpmlSymbols.TITLE, feed.getTitle());
|
||||
if (feed.getType() != null) {
|
||||
xs.attribute(null, OpmlSymbols.TYPE, feed.getType());
|
||||
}
|
||||
xs.attribute(null, OpmlSymbols.XMLURL, feed.getDownload_url());
|
||||
if (feed.getLink() != null) {
|
||||
xs.attribute(null, OpmlSymbols.HTMLURL, feed.getLink());
|
||||
}
|
||||
xs.endTag(null, OpmlSymbols.OUTLINE);
|
||||
}
|
||||
xs.endTag(null, OpmlSymbols.BODY);
|
||||
xs.endTag(null, OpmlSymbols.OPML);
|
||||
xs.endDocument();
|
||||
Log.d(TAG, "Finished writing document");
|
||||
}
|
||||
|
||||
public String fileExtension() {
|
||||
return "opml";
|
||||
}
|
||||
public String fileExtension() {
|
||||
return "opml";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue