Merge branch 'master' into develop

This commit is contained in:
Shinokuni 2020-08-02 15:27:01 +02:00
commit d1caa22982
5 changed files with 102 additions and 121 deletions

54
.gitignore vendored
View File

@ -96,32 +96,32 @@ gradle-app.setting
hs_err_pid*
# ---> macOS
*.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
*.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
\.idea/
@ -131,3 +131,5 @@ fastlane/Appfile
fastlane/Fastfile
Gemfile
mapping/

View File

@ -2,39 +2,87 @@ package com.readrops.api.opml
import android.content.Context
import android.net.Uri
import com.readrops.api.opml.model.Body
import com.readrops.api.opml.model.Head
import com.readrops.api.opml.model.OPML
import com.readrops.api.opml.model.Outline
import com.readrops.api.utils.LibUtils
import com.readrops.db.entities.Feed
import com.readrops.db.entities.Folder
import io.reactivex.Completable
import io.reactivex.Single
import org.simpleframework.xml.Serializer
import org.simpleframework.xml.core.Persister
import java.io.OutputStream
class OPMLParser {
object OPMLParser {
companion object {
@JvmStatic
fun read(uri: Uri, context: Context): Single<OPML> {
return Single.create { emitter ->
val fileString = LibUtils.fileToString(uri, context)
val serializer: Serializer = Persister()
@JvmStatic
fun read(uri: Uri, context: Context): Single<Map<Folder, List<Feed>>> {
return Single.create { emitter ->
val fileString = LibUtils.fileToString(uri, context)
val serializer: Serializer = Persister()
val opml: OPML = serializer.read(OPML::class.java, fileString)
val opml: OPML = serializer.read(OPML::class.java, fileString)
emitter.onSuccess(opml)
}
}
@JvmStatic
fun write(opml: OPML, outputStream: OutputStream): Completable {
return Completable.create { emitter ->
val serializer: Serializer = Persister()
serializer.write(opml, outputStream)
emitter.onComplete()
}
emitter.onSuccess(opmltoFoldersAndFeeds(opml))
}
}
@JvmStatic
fun write(foldersAndFeeds: Map<Folder, List<Feed>>, outputStream: OutputStream): Completable {
return Completable.create { emitter ->
val serializer: Serializer = Persister()
serializer.write(foldersAndFeedsToOPML(foldersAndFeeds), outputStream)
emitter.onComplete()
}
}
private fun opmltoFoldersAndFeeds(opml: OPML): Map<Folder, List<Feed>> {
val foldersAndFeeds: MutableMap<Folder, List<Feed>> = HashMap()
val body = opml.body!!
body.outlines?.forEach { outline ->
val folder = Folder(outline.title)
val feeds = arrayListOf<Feed>()
outline.outlines?.forEach { feedOutline ->
val feed = Feed().apply {
name = feedOutline.title
url = feedOutline.xmlUrl
siteUrl = feedOutline.htmlUrl
}
feeds.add(feed)
}
foldersAndFeeds[folder] = feeds
}
return foldersAndFeeds
}
private fun foldersAndFeedsToOPML(foldersAndFeeds: Map<Folder, List<Feed>>): OPML {
val outlines = arrayListOf<Outline>()
for (folderAndFeeds in foldersAndFeeds) {
val outline = Outline(folderAndFeeds.key.name)
val feedOutlines = arrayListOf<Outline>()
folderAndFeeds.value.forEach { feed ->
val feedOutline = Outline(feed.name, feed.url, feed.siteUrl)
feedOutlines.add(feedOutline)
}
outline.outlines = feedOutlines
outlines.add(outline)
}
val head = Head("Subscriptions")
val body = Body(outlines)
return OPML("2.0", head, body)
}
}

View File

@ -22,6 +22,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import com.afollestad.materialdialogs.MaterialDialog;
import com.readrops.api.opml.OPMLParser;
import com.readrops.app.R;
import com.readrops.app.ReadropsApp;
import com.readrops.app.activities.AddAccountActivity;
@ -30,12 +31,9 @@ import com.readrops.app.activities.NotificationPermissionActivity;
import com.readrops.app.utils.PermissionManager;
import com.readrops.app.utils.SharedPreferencesManager;
import com.readrops.app.utils.Utils;
import com.readrops.app.utils.matchers.OPMLMatcher;
import com.readrops.app.viewmodels.AccountViewModel;
import com.readrops.db.entities.account.Account;
import com.readrops.db.entities.account.AccountType;
import com.readrops.api.opml.OPMLParser;
import com.readrops.api.opml.model.OPML;
import java.io.File;
import java.io.FileOutputStream;
@ -247,11 +245,8 @@ public class AccountSettingsFragment extends PreferenceFragmentCompat {
final OutputStream outputStream = new FileOutputStream(file);
viewModel.getFoldersWithFeeds()
.flatMapCompletable(folderListMap -> {
OPML opml = OPMLMatcher.INSTANCE.foldersAndFeedsToOPML(folderListMap, getContext());
return OPMLParser.write(opml, outputStream);
}).subscribeOn(Schedulers.io())
.flatMapCompletable(folderListMap -> OPMLParser.write(folderListMap, outputStream))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doAfterTerminate(() -> {
try {

View File

@ -1,59 +0,0 @@
package com.readrops.app.utils.matchers
import android.content.Context
import com.readrops.app.R
import com.readrops.db.entities.Feed
import com.readrops.db.entities.Folder
import com.readrops.api.opml.model.Body
import com.readrops.api.opml.model.Head
import com.readrops.api.opml.model.OPML
import com.readrops.api.opml.model.Outline
object OPMLMatcher {
fun opmltoFoldersAndFeeds(opml: OPML): Map<Folder, List<Feed>> {
val foldersAndFeeds: MutableMap<Folder, List<Feed>> = HashMap()
val body = opml.body!!
body.outlines?.forEach { outline ->
val folder = Folder(outline.title)
val feeds = arrayListOf<Feed>()
outline.outlines?.forEach { feedOutline ->
val feed = Feed().apply {
name = feedOutline.title
url = feedOutline.xmlUrl
siteUrl = feedOutline.htmlUrl
}
feeds.add(feed)
}
foldersAndFeeds[folder] = feeds
}
return foldersAndFeeds
}
fun foldersAndFeedsToOPML(foldersAndFeeds: Map<Folder, List<Feed>>, context: Context): OPML {
val outlines = arrayListOf<Outline>()
for (folderAndFeeds in foldersAndFeeds) {
val outline = Outline(folderAndFeeds.key.name)
val feedOutlines = arrayListOf<Outline>()
folderAndFeeds.value.forEach { feed ->
val feedOutline = Outline(feed.name, feed.url, feed.siteUrl)
feedOutlines.add(feedOutline)
}
outline.outlines = feedOutlines
outlines.add(outline)
}
val head = Head(context.getString(R.string.subscriptions))
val body = Body(outlines)
return OPML("2.0", head, body)
}
}

View File

@ -7,14 +7,13 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import com.readrops.api.opml.OPMLParser;
import com.readrops.app.repositories.ARepository;
import com.readrops.db.Database;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.account.Account;
import com.readrops.db.entities.account.AccountType;
import com.readrops.app.repositories.ARepository;
import com.readrops.app.utils.matchers.OPMLMatcher;
import com.readrops.api.opml.OPMLParser;
import java.util.List;
import java.util.Map;
@ -73,10 +72,6 @@ public class AccountViewModel extends AndroidViewModel {
public Completable parseOPMLFile(Uri uri) {
return OPMLParser.read(uri, getApplication())
.flatMapCompletable(opml -> {
Map<Folder, List<Feed>> foldersAndFeeds = OPMLMatcher.INSTANCE.opmltoFoldersAndFeeds(opml);
return repository.insertOPMLFoldersAndFeeds(foldersAndFeeds);
});
.flatMapCompletable(foldersAndFeeds -> repository.insertOPMLFoldersAndFeeds(foldersAndFeeds));
}
}