Move notification API into main commons codebase (#5465)

* Moved the notification API calls out of the data client

* Converted the NofificationClient to kotlin and improved its test
This commit is contained in:
Paul Hawke 2024-01-23 07:43:37 -06:00 committed by GitHub
parent 1948bab873
commit 3c1cdf18a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 210 additions and 94 deletions

View file

@ -19,6 +19,7 @@ import fr.free.nrw.commons.media.PageMediaInterface;
import fr.free.nrw.commons.media.WikidataMediaInterface;
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
import fr.free.nrw.commons.mwapi.UserInterface;
import fr.free.nrw.commons.notification.NotificationInterface;
import fr.free.nrw.commons.review.ReviewInterface;
import fr.free.nrw.commons.upload.UploadInterface;
import fr.free.nrw.commons.upload.WikiBaseInterface;
@ -265,6 +266,14 @@ public class NetworkingModule {
.get(commonsWikiSite, BuildConfig.COMMONS_URL, ThanksInterface.class);
}
@Provides
@Singleton
public NotificationInterface provideNotificationInterface(
@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) {
return ServiceFactory
.get(commonsWikiSite, BuildConfig.COMMONS_URL, NotificationInterface.class);
}
@Provides
@Singleton
public UserInterface provideUserInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) {

View file

@ -1,46 +0,0 @@
package fr.free.nrw.commons.notification;
import fr.free.nrw.commons.notification.models.Notification;
import org.wikipedia.csrf.CsrfTokenClient;
import org.wikipedia.dataclient.Service;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import io.reactivex.Observable;
import io.reactivex.Single;
import static fr.free.nrw.commons.di.NetworkingModule.NAMED_COMMONS_CSRF;
@Singleton
public class NotificationClient {
private final Service service;
private final CsrfTokenClient csrfTokenClient;
@Inject
public NotificationClient(@Named("commons-service") Service service, @Named(NAMED_COMMONS_CSRF) CsrfTokenClient csrfTokenClient) {
this.service = service;
this.csrfTokenClient = csrfTokenClient;
}
public Single<List<Notification>> getNotifications(boolean archived) {
return service.getAllNotifications("wikidatawiki|commonswiki|enwiki", archived ? "read" : "!read", null)
.map(mwQueryResponse -> mwQueryResponse.query().notifications().list())
.flatMap(Observable::fromIterable)
.map(notification -> Notification.from(notification))
.toList();
}
public Observable<Boolean> markNotificationAsRead(String notificationId) {
try {
return service.markRead(csrfTokenClient.getTokenBlocking(), notificationId, "")
.map(mwQueryResponse -> mwQueryResponse.success());
} catch (Throwable throwable) {
return Observable.just(false);
}
}
}

View file

@ -0,0 +1,54 @@
package fr.free.nrw.commons.notification
import fr.free.nrw.commons.di.NetworkingModule
import fr.free.nrw.commons.notification.models.Notification
import fr.free.nrw.commons.notification.models.NotificationType
import io.reactivex.Observable
import io.reactivex.Single
import org.wikipedia.csrf.CsrfTokenClient
import org.wikipedia.dataclient.mwapi.MwQueryResponse
import org.wikipedia.util.DateUtil
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Singleton
import org.wikipedia.notifications.Notification as WikimediaNotification
@Singleton
class NotificationClient @Inject constructor(
@param:Named(NetworkingModule.NAMED_COMMONS_CSRF) private val csrfTokenClient: CsrfTokenClient,
private val service: NotificationInterface
) {
fun getNotifications(archived: Boolean): Single<List<Notification>> =
service.getAllNotifications(
wikiList = "wikidatawiki|commonswiki|enwiki",
filter = if (archived) "read" else "!read",
continueStr = null
).map {
it.query()?.notifications()?.list() ?: emptyList()
}.flatMap {
Observable.fromIterable(it)
}.map {
it.toCommonsNotification()
}.toList()
fun markNotificationAsRead(notificationId: String?): Observable<Boolean> {
return try {
service.markRead(
token = csrfTokenClient.tokenBlocking,
readList = notificationId,
unreadList = ""
).map(MwQueryResponse::success)
} catch (throwable: Throwable) {
Observable.just(false)
}
}
private fun WikimediaNotification.toCommonsNotification() = Notification(
notificationType = NotificationType.UNKNOWN,
notificationText = contents?.compactHeader ?: "",
date = DateUtil.getMonthOnlyDateString(timestamp),
link = contents?.links?.primary?.url ?: "",
iconUrl = "",
notificationId = id().toString()
)
}

View file

@ -0,0 +1,31 @@
package fr.free.nrw.commons.notification
import io.reactivex.Observable
import org.wikipedia.dataclient.Service
import org.wikipedia.dataclient.mwapi.MwQueryResponse
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.POST
import retrofit2.http.Query
interface NotificationInterface {
@Headers("Cache-Control: no-cache")
@GET(Service.MW_API_PREFIX + "action=query&meta=notifications&notformat=model&notlimit=max")
fun getAllNotifications(
@Query("notwikis") wikiList: String?,
@Query("notfilter") filter: String?,
@Query("notcontinue") continueStr: String?
): Observable<MwQueryResponse?>
@FormUrlEncoded
@Headers("Cache-Control: no-cache")
@POST(Service.MW_API_PREFIX + "action=echomarkread")
fun markRead(
@Field("token") token: String,
@Field("list") readList: String?,
@Field("unreadlist") unreadList: String?
): Observable<MwQueryResponse?>
}

View file

@ -1,29 +1,13 @@
package fr.free.nrw.commons.notification.models
import org.wikipedia.util.DateUtil
/**
* Created by root on 18.12.2017.
*/
data class Notification(var notificationType: NotificationType,
var notificationText: String,
var date: String,
var link: String,
var iconUrl: String,
var notificationId: String) {
companion object {
@JvmStatic
fun from(wikiNotification: org.wikipedia.notifications.Notification): Notification {
val contents = wikiNotification.contents
val notificationLink = if (contents == null || contents.links == null || contents.links!!.primary == null) "" else contents.links!!.primary!!.url
return Notification(
NotificationType.UNKNOWN,
contents?.compactHeader ?: "",
DateUtil.getMonthOnlyDateString(wikiNotification.timestamp),
notificationLink,
"", wikiNotification.id().toString())
}
}
}
data class Notification(
var notificationType: NotificationType,
var notificationText: String,
var date: String,
var link: String,
var iconUrl: String,
var notificationId: String
)