Partial migration of data package to Kotlin
This commit is contained in:
@@ -1,40 +0,0 @@
|
||||
package eu.kanade.tachiyomi.data.mangasync;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import eu.kanade.tachiyomi.data.mangasync.base.MangaSyncService;
|
||||
import eu.kanade.tachiyomi.data.mangasync.services.MyAnimeList;
|
||||
|
||||
public class MangaSyncManager {
|
||||
|
||||
private List<MangaSyncService> services;
|
||||
private MyAnimeList myAnimeList;
|
||||
|
||||
public static final int MYANIMELIST = 1;
|
||||
|
||||
public MangaSyncManager(Context context) {
|
||||
services = new ArrayList<>();
|
||||
myAnimeList = new MyAnimeList(context);
|
||||
services.add(myAnimeList);
|
||||
}
|
||||
|
||||
public MyAnimeList getMyAnimeList() {
|
||||
return myAnimeList;
|
||||
}
|
||||
|
||||
public List<MangaSyncService> getSyncServices() {
|
||||
return services;
|
||||
}
|
||||
|
||||
public MangaSyncService getSyncService(int id) {
|
||||
switch (id) {
|
||||
case MYANIMELIST:
|
||||
return myAnimeList;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package eu.kanade.tachiyomi.data.mangasync
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.data.mangasync.base.MangaSyncService
|
||||
import eu.kanade.tachiyomi.data.mangasync.services.MyAnimeList
|
||||
|
||||
class MangaSyncManager(private val context: Context) {
|
||||
|
||||
val services: List<MangaSyncService>
|
||||
val myAnimeList: MyAnimeList
|
||||
|
||||
companion object {
|
||||
const val MYANIMELIST = 1
|
||||
}
|
||||
|
||||
init {
|
||||
myAnimeList = MyAnimeList(context, MYANIMELIST)
|
||||
services = listOf(myAnimeList)
|
||||
}
|
||||
|
||||
fun getService(id: Int): MangaSyncService = services.find { it.id == id }!!
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package eu.kanade.tachiyomi.data.mangasync
|
||||
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.IBinder
|
||||
import eu.kanade.tachiyomi.App
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaSync
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.schedulers.Schedulers
|
||||
import rx.subscriptions.CompositeSubscription
|
||||
import javax.inject.Inject
|
||||
|
||||
class UpdateMangaSyncService : Service() {
|
||||
|
||||
@Inject lateinit var syncManager: MangaSyncManager
|
||||
@Inject lateinit var db: DatabaseHelper
|
||||
|
||||
private lateinit var subscriptions: CompositeSubscription
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
App.get(this).component.inject(this)
|
||||
subscriptions = CompositeSubscription()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
subscriptions.unsubscribe()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
val manga = intent.getSerializableExtra(EXTRA_MANGASYNC)
|
||||
if (manga != null) {
|
||||
updateLastChapterRead(manga as MangaSync, startId)
|
||||
return Service.START_REDELIVER_INTENT
|
||||
} else {
|
||||
stopSelf(startId)
|
||||
return Service.START_NOT_STICKY
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun updateLastChapterRead(mangaSync: MangaSync, startId: Int) {
|
||||
val sync = syncManager.getService(mangaSync.sync_id)
|
||||
|
||||
subscriptions.add(Observable.defer { sync.update(mangaSync) }
|
||||
.flatMap {
|
||||
if (it.isSuccessful) {
|
||||
db.insertMangaSync(mangaSync).asRxObservable()
|
||||
} else {
|
||||
Observable.error(Exception("Could not update manga in remote service"))
|
||||
}
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ stopSelf(startId) },
|
||||
{ stopSelf(startId) }))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val EXTRA_MANGASYNC = "extra_mangasync"
|
||||
|
||||
@JvmStatic
|
||||
fun start(context: Context, mangaSync: MangaSync) {
|
||||
val intent = Intent(context, UpdateMangaSyncService::class.java)
|
||||
intent.putExtra(EXTRA_MANGASYNC, mangaSync)
|
||||
context.startService(intent)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package eu.kanade.tachiyomi.data.mangasync.base;
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaSync;
|
||||
import okhttp3.Response;
|
||||
import rx.Observable;
|
||||
|
||||
public abstract class MangaSyncService {
|
||||
|
||||
// Name of the manga sync service to display
|
||||
public abstract String getName();
|
||||
|
||||
// Id of the sync service (must be declared and obtained from MangaSyncManager to avoid conflicts)
|
||||
public abstract int getId();
|
||||
|
||||
public abstract Observable<Boolean> login(String username, String password);
|
||||
|
||||
public abstract boolean isLogged();
|
||||
|
||||
public abstract Observable<Response> update(MangaSync manga);
|
||||
|
||||
public abstract Observable<Response> add(MangaSync manga);
|
||||
|
||||
public abstract Observable<Response> bind(MangaSync manga);
|
||||
|
||||
public abstract String getStatus(int status);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package eu.kanade.tachiyomi.data.mangasync.base
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.App
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaSync
|
||||
import eu.kanade.tachiyomi.data.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import okhttp3.Response
|
||||
import rx.Observable
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class MangaSyncService(private val context: Context, val id: Int) {
|
||||
|
||||
@Inject lateinit var preferences: PreferencesHelper
|
||||
@Inject lateinit var networkService: NetworkHelper
|
||||
|
||||
init {
|
||||
App.get(context).component.inject(this)
|
||||
}
|
||||
|
||||
// Name of the manga sync service to display
|
||||
abstract val name: String
|
||||
|
||||
abstract fun login(username: String, password: String): Observable<Boolean>
|
||||
|
||||
open val isLogged: Boolean
|
||||
get() = !preferences.getMangaSyncUsername(this).isEmpty() &&
|
||||
!preferences.getMangaSyncPassword(this).isEmpty()
|
||||
|
||||
abstract fun update(manga: MangaSync): Observable<Response>
|
||||
|
||||
abstract fun add(manga: MangaSync): Observable<Response>
|
||||
|
||||
abstract fun bind(manga: MangaSync): Observable<Response>
|
||||
|
||||
abstract fun getStatus(status: Int): String
|
||||
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
package eu.kanade.tachiyomi.data.mangasync.services;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.util.Xml;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import eu.kanade.tachiyomi.App;
|
||||
import eu.kanade.tachiyomi.R;
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaSync;
|
||||
import eu.kanade.tachiyomi.data.mangasync.MangaSyncManager;
|
||||
import eu.kanade.tachiyomi.data.mangasync.base.MangaSyncService;
|
||||
import eu.kanade.tachiyomi.data.network.NetworkHelper;
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper;
|
||||
import okhttp3.Credentials;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import rx.Observable;
|
||||
|
||||
public class MyAnimeList extends MangaSyncService {
|
||||
|
||||
@Inject PreferencesHelper preferences;
|
||||
@Inject NetworkHelper networkService;
|
||||
|
||||
private Headers headers;
|
||||
private String username;
|
||||
|
||||
public static final String BASE_URL = "http://myanimelist.net";
|
||||
|
||||
private static final String ENTRY_TAG = "entry";
|
||||
private static final String CHAPTER_TAG = "chapter";
|
||||
private static final String SCORE_TAG = "score";
|
||||
private static final String STATUS_TAG = "status";
|
||||
|
||||
public static final int READING = 1;
|
||||
public static final int COMPLETED = 2;
|
||||
public static final int ON_HOLD = 3;
|
||||
public static final int DROPPED = 4;
|
||||
public static final int PLAN_TO_READ = 6;
|
||||
|
||||
public static final int DEFAULT_STATUS = READING;
|
||||
public static final int DEFAULT_SCORE = 0;
|
||||
|
||||
private Context context;
|
||||
|
||||
public MyAnimeList(Context context) {
|
||||
this.context = context;
|
||||
App.get(context).getComponent().inject(this);
|
||||
|
||||
String username = preferences.getMangaSyncUsername(this);
|
||||
String password = preferences.getMangaSyncPassword(this);
|
||||
|
||||
if (!username.isEmpty() && !password.isEmpty()) {
|
||||
createHeaders(username, password);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "MyAnimeList";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return MangaSyncManager.MYANIMELIST;
|
||||
}
|
||||
|
||||
public String getLoginUrl() {
|
||||
return Uri.parse(BASE_URL).buildUpon()
|
||||
.appendEncodedPath("api/account/verify_credentials.xml")
|
||||
.toString();
|
||||
}
|
||||
|
||||
public Observable<Boolean> login(String username, String password) {
|
||||
createHeaders(username, password);
|
||||
return networkService.getResponse(getLoginUrl(), headers, false)
|
||||
.map(response -> response.code() == 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogged() {
|
||||
return !preferences.getMangaSyncUsername(this).isEmpty()
|
||||
&& !preferences.getMangaSyncPassword(this).isEmpty();
|
||||
}
|
||||
|
||||
public String getSearchUrl(String query) {
|
||||
return Uri.parse(BASE_URL).buildUpon()
|
||||
.appendEncodedPath("api/manga/search.xml")
|
||||
.appendQueryParameter("q", query)
|
||||
.toString();
|
||||
}
|
||||
|
||||
public Observable<List<MangaSync>> search(String query) {
|
||||
return networkService.getStringResponse(getSearchUrl(query), headers, true)
|
||||
.map(Jsoup::parse)
|
||||
.flatMap(doc -> Observable.from(doc.select("entry")))
|
||||
.filter(entry -> !entry.select("type").text().equals("Novel"))
|
||||
.map(entry -> {
|
||||
MangaSync manga = MangaSync.create(this);
|
||||
manga.title = entry.select("title").first().text();
|
||||
manga.remote_id = Integer.parseInt(entry.select("id").first().text());
|
||||
manga.total_chapters = Integer.parseInt(entry.select("chapters").first().text());
|
||||
return manga;
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
|
||||
public String getListUrl(String username) {
|
||||
return Uri.parse(BASE_URL).buildUpon()
|
||||
.appendPath("malappinfo.php")
|
||||
.appendQueryParameter("u", username)
|
||||
.appendQueryParameter("status", "all")
|
||||
.appendQueryParameter("type", "manga")
|
||||
.toString();
|
||||
}
|
||||
|
||||
public Observable<List<MangaSync>> getList() {
|
||||
// TODO cache this list for a few minutes
|
||||
return networkService.getStringResponse(getListUrl(username), headers, true)
|
||||
.map(Jsoup::parse)
|
||||
.flatMap(doc -> Observable.from(doc.select("manga")))
|
||||
.map(entry -> {
|
||||
MangaSync manga = MangaSync.create(this);
|
||||
manga.title = entry.select("series_title").first().text();
|
||||
manga.remote_id = Integer.parseInt(
|
||||
entry.select("series_mangadb_id").first().text());
|
||||
manga.last_chapter_read = Integer.parseInt(
|
||||
entry.select("my_read_chapters").first().text());
|
||||
manga.status = Integer.parseInt(
|
||||
entry.select("my_status").first().text());
|
||||
// MAL doesn't support score with decimals
|
||||
manga.score = Integer.parseInt(
|
||||
entry.select("my_score").first().text());
|
||||
manga.total_chapters = Integer.parseInt(
|
||||
entry.select("series_chapters").first().text());
|
||||
return manga;
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
|
||||
public String getUpdateUrl(MangaSync manga) {
|
||||
return Uri.parse(BASE_URL).buildUpon()
|
||||
.appendEncodedPath("api/mangalist/update")
|
||||
.appendPath(manga.remote_id + ".xml")
|
||||
.toString();
|
||||
}
|
||||
|
||||
public Observable<Response> update(MangaSync manga) {
|
||||
try {
|
||||
if (manga.total_chapters != 0 && manga.last_chapter_read == manga.total_chapters) {
|
||||
manga.status = COMPLETED;
|
||||
}
|
||||
RequestBody payload = getMangaPostPayload(manga);
|
||||
return networkService.postData(getUpdateUrl(manga), payload, headers);
|
||||
} catch (IOException e) {
|
||||
return Observable.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getAddUrl(MangaSync manga) {
|
||||
return Uri.parse(BASE_URL).buildUpon()
|
||||
.appendEncodedPath("api/mangalist/add")
|
||||
.appendPath(manga.remote_id + ".xml")
|
||||
.toString();
|
||||
}
|
||||
|
||||
public Observable<Response> add(MangaSync manga) {
|
||||
try {
|
||||
RequestBody payload = getMangaPostPayload(manga);
|
||||
return networkService.postData(getAddUrl(manga), payload, headers);
|
||||
} catch (IOException e) {
|
||||
return Observable.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private RequestBody getMangaPostPayload(MangaSync manga) throws IOException {
|
||||
XmlSerializer xml = Xml.newSerializer();
|
||||
StringWriter writer = new StringWriter();
|
||||
xml.setOutput(writer);
|
||||
xml.startDocument("UTF-8", false);
|
||||
xml.startTag("", ENTRY_TAG);
|
||||
|
||||
// Last chapter read
|
||||
if (manga.last_chapter_read != 0) {
|
||||
xml.startTag("", CHAPTER_TAG);
|
||||
xml.text(manga.last_chapter_read + "");
|
||||
xml.endTag("", CHAPTER_TAG);
|
||||
}
|
||||
// Manga status in the list
|
||||
xml.startTag("", STATUS_TAG);
|
||||
xml.text(manga.status + "");
|
||||
xml.endTag("", STATUS_TAG);
|
||||
// Manga score
|
||||
xml.startTag("", SCORE_TAG);
|
||||
xml.text(manga.score + "");
|
||||
xml.endTag("", SCORE_TAG);
|
||||
|
||||
xml.endTag("", ENTRY_TAG);
|
||||
xml.endDocument();
|
||||
|
||||
FormBody.Builder form = new FormBody.Builder();
|
||||
form.add("data", writer.toString());
|
||||
return form.build();
|
||||
}
|
||||
|
||||
public Observable<Response> bind(MangaSync manga) {
|
||||
return getList()
|
||||
.flatMap(list -> {
|
||||
manga.sync_id = getId();
|
||||
for (MangaSync remoteManga : list) {
|
||||
if (remoteManga.remote_id == manga.remote_id) {
|
||||
// Manga is already in the list
|
||||
manga.copyPersonalFrom(remoteManga);
|
||||
return update(manga);
|
||||
}
|
||||
}
|
||||
// Set default fields if it's not found in the list
|
||||
manga.score = DEFAULT_SCORE;
|
||||
manga.status = DEFAULT_STATUS;
|
||||
return add(manga);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatus(int status) {
|
||||
switch (status) {
|
||||
case READING:
|
||||
return context.getString(R.string.reading);
|
||||
case COMPLETED:
|
||||
return context.getString(R.string.completed);
|
||||
case ON_HOLD:
|
||||
return context.getString(R.string.on_hold);
|
||||
case DROPPED:
|
||||
return context.getString(R.string.dropped);
|
||||
case PLAN_TO_READ:
|
||||
return context.getString(R.string.plan_to_read);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public void createHeaders(String username, String password) {
|
||||
this.username = username;
|
||||
Headers.Builder builder = new Headers.Builder();
|
||||
builder.add("Authorization", Credentials.basic(username, password));
|
||||
builder.add("User-Agent", "api-indiv-9F93C52A963974CF674325391990191C");
|
||||
setHeaders(builder.build());
|
||||
}
|
||||
|
||||
public void setHeaders(Headers headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
package eu.kanade.tachiyomi.data.mangasync.services
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.util.Xml
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaSync
|
||||
import eu.kanade.tachiyomi.data.mangasync.base.MangaSyncService
|
||||
import eu.kanade.tachiyomi.data.network.get
|
||||
import eu.kanade.tachiyomi.data.network.post
|
||||
import eu.kanade.tachiyomi.util.selectInt
|
||||
import eu.kanade.tachiyomi.util.selectText
|
||||
import okhttp3.*
|
||||
import org.jsoup.Jsoup
|
||||
import org.xmlpull.v1.XmlSerializer
|
||||
import rx.Observable
|
||||
import java.io.StringWriter
|
||||
|
||||
fun XmlSerializer.inTag(tag: String, body: String, namespace: String = "") {
|
||||
startTag(namespace, tag)
|
||||
text(body)
|
||||
endTag(namespace, tag)
|
||||
}
|
||||
|
||||
class MyAnimeList(private val context: Context, id: Int) : MangaSyncService(context, id) {
|
||||
|
||||
private lateinit var headers: Headers
|
||||
private lateinit var username: String
|
||||
|
||||
companion object {
|
||||
val BASE_URL = "http://myanimelist.net"
|
||||
|
||||
private val ENTRY_TAG = "entry"
|
||||
private val CHAPTER_TAG = "chapter"
|
||||
private val SCORE_TAG = "score"
|
||||
private val STATUS_TAG = "status"
|
||||
|
||||
val READING = 1
|
||||
val COMPLETED = 2
|
||||
val ON_HOLD = 3
|
||||
val DROPPED = 4
|
||||
val PLAN_TO_READ = 6
|
||||
|
||||
val DEFAULT_STATUS = READING
|
||||
val DEFAULT_SCORE = 0
|
||||
}
|
||||
|
||||
init {
|
||||
val username = preferences.getMangaSyncUsername(this)
|
||||
val password = preferences.getMangaSyncPassword(this)
|
||||
|
||||
if (!username.isEmpty() && !password.isEmpty()) {
|
||||
createHeaders(username, password)
|
||||
}
|
||||
}
|
||||
|
||||
override val name: String
|
||||
get() = "MyAnimeList"
|
||||
|
||||
fun getLoginUrl(): String {
|
||||
return Uri.parse(BASE_URL).buildUpon()
|
||||
.appendEncodedPath("api/account/verify_credentials.xml")
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun login(username: String, password: String): Observable<Boolean> {
|
||||
createHeaders(username, password)
|
||||
return networkService.request(get(getLoginUrl(), headers))
|
||||
.map { it.code() == 200 }
|
||||
}
|
||||
|
||||
fun getSearchUrl(query: String): String {
|
||||
return Uri.parse(BASE_URL).buildUpon()
|
||||
.appendEncodedPath("api/manga/search.xml")
|
||||
.appendQueryParameter("q", query)
|
||||
.toString()
|
||||
}
|
||||
|
||||
fun search(query: String): Observable<List<MangaSync>> {
|
||||
return networkService.requestBody(get(getSearchUrl(query), headers))
|
||||
.map { Jsoup.parse(it) }
|
||||
.flatMap { Observable.from(it.select("entry")) }
|
||||
.filter { it.select("type").text() != "Novel" }
|
||||
.map {
|
||||
val manga = MangaSync.create(this)
|
||||
manga.title = it.selectText("title")
|
||||
manga.remote_id = it.selectInt("id")
|
||||
manga.total_chapters = it.selectInt("chapters")
|
||||
manga
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun getListUrl(username: String): String {
|
||||
return Uri.parse(BASE_URL).buildUpon()
|
||||
.appendPath("malappinfo.php")
|
||||
.appendQueryParameter("u", username)
|
||||
.appendQueryParameter("status", "all")
|
||||
.appendQueryParameter("type", "manga")
|
||||
.toString()
|
||||
}
|
||||
|
||||
// MAL doesn't support score with decimals
|
||||
fun getList(): Observable<List<MangaSync>> {
|
||||
return networkService.requestBody(get(getListUrl(username), headers), true)
|
||||
.map { Jsoup.parse(it) }
|
||||
.flatMap { Observable.from(it.select("manga")) }
|
||||
.map {
|
||||
val manga = MangaSync.create(this)
|
||||
manga.title = it.selectText("series_title")
|
||||
manga.remote_id = it.selectInt("series_mangadb_id")
|
||||
manga.last_chapter_read = it.selectInt("my_read_chapters")
|
||||
manga.status = it.selectInt("my_status")
|
||||
manga.score = it.selectInt("my_score").toFloat()
|
||||
manga.total_chapters = it.selectInt("series_chapters")
|
||||
manga
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun getUpdateUrl(manga: MangaSync): String {
|
||||
return Uri.parse(BASE_URL).buildUpon()
|
||||
.appendEncodedPath("api/mangalist/update")
|
||||
.appendPath(manga.remote_id.toString() + ".xml")
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun update(manga: MangaSync): Observable<Response> {
|
||||
return Observable.defer {
|
||||
if (manga.total_chapters != 0 && manga.last_chapter_read == manga.total_chapters) {
|
||||
manga.status = COMPLETED
|
||||
}
|
||||
networkService.request(post(getUpdateUrl(manga), headers, getMangaPostPayload(manga)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun getAddUrl(manga: MangaSync): String {
|
||||
return Uri.parse(BASE_URL).buildUpon()
|
||||
.appendEncodedPath("api/mangalist/add")
|
||||
.appendPath(manga.remote_id.toString() + ".xml")
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun add(manga: MangaSync): Observable<Response> {
|
||||
return Observable.defer {
|
||||
networkService.request(post(getAddUrl(manga), headers, getMangaPostPayload(manga)))
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMangaPostPayload(manga: MangaSync): RequestBody {
|
||||
val xml = Xml.newSerializer()
|
||||
val writer = StringWriter()
|
||||
|
||||
with(xml) {
|
||||
setOutput(writer)
|
||||
startDocument("UTF-8", false)
|
||||
startTag("", ENTRY_TAG)
|
||||
|
||||
// Last chapter read
|
||||
if (manga.last_chapter_read != 0) {
|
||||
inTag(CHAPTER_TAG, manga.last_chapter_read.toString())
|
||||
}
|
||||
// Manga status in the list
|
||||
inTag(STATUS_TAG, manga.status.toString())
|
||||
|
||||
// Manga score
|
||||
inTag(SCORE_TAG, manga.score.toString())
|
||||
|
||||
endTag("", ENTRY_TAG)
|
||||
endDocument()
|
||||
}
|
||||
|
||||
val form = FormBody.Builder()
|
||||
form.add("data", writer.toString())
|
||||
return form.build()
|
||||
}
|
||||
|
||||
override fun bind(manga: MangaSync): Observable<Response> {
|
||||
return getList()
|
||||
.flatMap {
|
||||
manga.sync_id = id
|
||||
for (remoteManga in it) {
|
||||
if (remoteManga.remote_id == manga.remote_id) {
|
||||
// Manga is already in the list
|
||||
manga.copyPersonalFrom(remoteManga)
|
||||
return@flatMap update(manga)
|
||||
}
|
||||
}
|
||||
// Set default fields if it's not found in the list
|
||||
manga.score = DEFAULT_SCORE.toFloat()
|
||||
manga.status = DEFAULT_STATUS
|
||||
return@flatMap add(manga)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getStatus(status: Int): String = with(context) {
|
||||
when (status) {
|
||||
READING -> getString(R.string.reading)
|
||||
COMPLETED -> getString(R.string.completed)
|
||||
ON_HOLD -> getString(R.string.on_hold)
|
||||
DROPPED -> getString(R.string.dropped)
|
||||
PLAN_TO_READ -> getString(R.string.plan_to_read)
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun createHeaders(username: String, password: String) {
|
||||
this.username = username
|
||||
val builder = Headers.Builder()
|
||||
builder.add("Authorization", Credentials.basic(username, password))
|
||||
builder.add("User-Agent", "api-indiv-9F93C52A963974CF674325391990191C")
|
||||
headers = builder.build()
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user