1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
package org.terst.feedreader.opml
import android.util.Xml
import org.terst.feedreader.data.FeedEntity
import org.xmlpull.v1.XmlPullParser
import java.io.InputStream
import java.io.OutputStream
data class OpmlFeed(val title: String, val xmlUrl: String, val htmlUrl: String?)
/**
* OPML import/export. Any folder nesting (<outline> containing other
* <outline> elements instead of an xmlUrl) is flattened -- this app has no
* folder concept, per the "simple design" scope, so a folder's contents
* are just imported as a flat list of feeds.
*/
object Opml {
fun parse(input: InputStream): List<OpmlFeed> {
val parser = Xml.newPullParser()
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
parser.setInput(input, null)
val feeds = mutableListOf<OpmlFeed>()
var eventType = parser.eventType
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG && parser.name.equals("outline", ignoreCase = true)) {
val xmlUrl = parser.getAttributeValue(null, "xmlUrl")
if (xmlUrl != null) {
val title = parser.getAttributeValue(null, "title")
?: parser.getAttributeValue(null, "text")
?: xmlUrl
val htmlUrl = parser.getAttributeValue(null, "htmlUrl")
feeds += OpmlFeed(title, xmlUrl, htmlUrl)
}
}
eventType = parser.next()
}
return feeds
}
fun write(feeds: List<FeedEntity>, output: OutputStream) {
val serializer = Xml.newSerializer()
serializer.setOutput(output, "UTF-8")
serializer.startDocument("UTF-8", true)
serializer.startTag(null, "opml")
serializer.attribute(null, "version", "2.0")
serializer.startTag(null, "head")
serializer.startTag(null, "title")
serializer.text("Feeds subscriptions")
serializer.endTag(null, "title")
serializer.endTag(null, "head")
serializer.startTag(null, "body")
for (feed in feeds) {
serializer.startTag(null, "outline")
serializer.attribute(null, "text", feed.title)
serializer.attribute(null, "title", feed.title)
serializer.attribute(null, "type", "rss")
serializer.attribute(null, "xmlUrl", feed.id)
feed.siteUrl?.let { serializer.attribute(null, "htmlUrl", it) }
serializer.endTag(null, "outline")
}
serializer.endTag(null, "body")
serializer.endTag(null, "opml")
serializer.endDocument()
serializer.flush()
}
}
|