#747: Convert action package (ThanksClient and PageEditClient) to Kotlin (#4075)

This commit is contained in:
Adam Jones 2021-01-23 09:06:01 +00:00 committed by GitHub
parent 36406bad85
commit 89737b2640
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 180 additions and 210 deletions

View file

@ -1,80 +0,0 @@
package fr.free.nrw.commons.actions;
import io.reactivex.Single;
import io.reactivex.SingleOnSubscribe;
import org.wikipedia.csrf.CsrfTokenClient;
import org.wikipedia.dataclient.Service;
import io.reactivex.Observable;
/**
* This class acts as a Client to facilitate wiki page editing
* services to various dependency providing modules such as the Network module, the Review Controller ,etc
*
* The methods provided by this class will post to the Media wiki api
* documented at: https://commons.wikimedia.org/w/api.php?action=help&modules=edit
*/
public class PageEditClient {
private final CsrfTokenClient csrfTokenClient;
private final PageEditInterface pageEditInterface;
private final Service service;
public PageEditClient(CsrfTokenClient csrfTokenClient,
PageEditInterface pageEditInterface,
Service service) {
this.csrfTokenClient = csrfTokenClient;
this.pageEditInterface = pageEditInterface;
this.service = service;
}
/**
* This method is used when the content of the page is to be replaced by new content received
* @param pageTitle Title of the page to edit
* @param text Holds the page content
* @param summary Edit summary
*/
public Observable<Boolean> edit(String pageTitle, String text, String summary) {
try {
return pageEditInterface.postEdit(pageTitle, summary, text, csrfTokenClient.getTokenBlocking())
.map(editResponse -> editResponse.edit().editSucceeded());
} catch (Throwable throwable) {
return Observable.just(false);
}
}
/**
* This method is used when we need to append something to the end of wiki page content
* @param pageTitle Title of the page to edit
* @param appendText The received page content is added to beginning of the page
* @param summary Edit summary
*/
public Observable<Boolean> appendEdit(String pageTitle, String appendText, String summary) {
return Single.create((SingleOnSubscribe<String>) emitter -> {
try {
emitter.onSuccess(csrfTokenClient.getTokenBlocking());
} catch (Throwable throwable) {
emitter.onError(throwable);
throwable.printStackTrace();
}
}).flatMapObservable(token -> pageEditInterface.postAppendEdit(pageTitle, summary, appendText, token)
.map(editResponse -> editResponse.edit().editSucceeded()));
}
/**
* This method is used when we need to add something to the starting of the page
* @param pageTitle Title of the page to edit
* @param prependText The received page content is added to beginning of the page
* @param summary Edit summary
*/
public Observable<Boolean> prependEdit(String pageTitle, String prependText, String summary) {
try {
return pageEditInterface.postPrependEdit(pageTitle, summary, prependText, csrfTokenClient.getTokenBlocking())
.map(editResponse -> editResponse.edit().editSucceeded());
} catch (Throwable throwable) {
return Observable.just(false);
}
}
}

View file

@ -0,0 +1,65 @@
package fr.free.nrw.commons.actions
import io.reactivex.Observable
import org.wikipedia.csrf.CsrfTokenClient
/**
* This class acts as a Client to facilitate wiki page editing
* services to various dependency providing modules such as the Network module, the Review Controller ,etc
*
* The methods provided by this class will post to the Media wiki api
* documented at: https://commons.wikimedia.org/w/api.php?action=help&modules=edit
*/
class PageEditClient(
private val csrfTokenClient: CsrfTokenClient,
private val pageEditInterface: PageEditInterface
) {
/**
* Replace the content of a wiki page
* @param pageTitle Title of the page to edit
* @param text Holds the page content
* @param summary Edit summary
* @return whether the edit was successful
*/
fun edit(pageTitle: String, text: String, summary: String): Observable<Boolean> {
return try {
pageEditInterface.postEdit(pageTitle, summary, text, csrfTokenClient.tokenBlocking)
.map { editResponse -> editResponse.edit()!!.editSucceeded() }
} catch (throwable: Throwable) {
Observable.just(false)
}
}
/**
* Append text to the end of a wiki page
* @param pageTitle Title of the page to edit
* @param appendText The received page content is added to the end of the page
* @param summary Edit summary
* @return whether the edit was successful
*/
fun appendEdit(pageTitle: String, appendText: String, summary: String): Observable<Boolean> {
return try {
pageEditInterface.postAppendEdit(pageTitle, summary, appendText, csrfTokenClient.tokenBlocking)
.map { editResponse -> editResponse.edit()!!.editSucceeded() }
} catch (throwable: Throwable) {
Observable.just(false)
}
}
/**
* Prepend text to the beginning of a wiki page
* @param pageTitle Title of the page to edit
* @param prependText The received page content is added to the beginning of the page
* @param summary Edit summary
* @return whether the edit was successful
*/
fun prependEdit(pageTitle: String, prependText: String, summary: String): Observable<Boolean> {
return try {
pageEditInterface.postPrependEdit(pageTitle, summary, prependText, csrfTokenClient.tokenBlocking)
.map { editResponse -> editResponse.edit()!!.editSucceeded() }
} catch (throwable: Throwable) {
Observable.just(false)
}
}
}

View file

@ -1,76 +0,0 @@
package fr.free.nrw.commons.actions;
import androidx.annotation.NonNull;
import org.wikipedia.edit.Edit;
import io.reactivex.Observable;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import static org.wikipedia.dataclient.Service.MW_API_PREFIX;
/**
* This interface facilitates wiki commons page editing services to the Networking module
* which provides all network related services used by the app.
*
* This interface posts a form encoded request to the wikimedia API
* with editing action as argument to edit a particular page
*/
public interface PageEditInterface {
/**
* This method posts such that the Content which the page
* has will be completely replaced by the value being passed to the
* "text" field of the encoded form data
* @param title Title of the page to edit. Cannot be used together with pageid.
* @param summary Edit summary. Also section title when section=new and sectiontitle is not set
* @param text Holds the page content
* @param token A "csrf" token
*/
@FormUrlEncoded
@Headers("Cache-Control: no-cache")
@POST(MW_API_PREFIX + "action=edit")
@NonNull
Observable<Edit> postEdit(@NonNull @Field("title") String title,
@NonNull @Field("summary") String summary,
@NonNull @Field("text") String text,
// NOTE: This csrf shold always be sent as the last field of form data
@NonNull @Field("token") String token);
/**
* This method posts such that the Content which the page
* has will be completely replaced by the value being passed to the
* "text" field of the encoded form data
* @param title Title of the page to edit. Cannot be used together with pageid.
* @param summary Edit summary. Also section title when section=new and sectiontitle is not set
* @param text The received page content is added to beginning of the page
* @param token A "csrf" token
*/
@FormUrlEncoded
@Headers("Cache-Control: no-cache")
@POST(MW_API_PREFIX + "action=edit")
@NonNull Observable<Edit> postAppendEdit(@NonNull @Field("title") String title,
@NonNull @Field("summary") String summary,
@NonNull @Field("appendtext") String text,
@NonNull @Field("token") String token);
/**
* This method posts such that the Content which the page
* has will be completely replaced by the value being passed to the
* "text" field of the encoded form data
* @param title Title of the page to edit. Cannot be used together with pageid.
* @param summary Edit summary. Also section title when section=new and sectiontitle is not set
* @param text The received page content is added to beginning of the page
* @param token A "csrf" token
*/
@FormUrlEncoded
@Headers("Cache-Control: no-cache")
@POST(MW_API_PREFIX + "action=edit")
@NonNull Observable<Edit> postPrependEdit(@NonNull @Field("title") String title,
@NonNull @Field("summary") String summary,
@NonNull @Field("prependtext") String text,
@NonNull @Field("token") String token);
}

View file

@ -0,0 +1,76 @@
package fr.free.nrw.commons.actions
import io.reactivex.Observable
import org.wikipedia.dataclient.Service
import org.wikipedia.edit.Edit
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.Headers
import retrofit2.http.POST
/**
* This interface facilitates wiki commons page editing services to the Networking module
* which provides all network related services used by the app.
*
* This interface posts a form encoded request to the wikimedia API
* with editing action as argument to edit a particular page
*/
interface PageEditInterface {
/**
* This method posts such that the Content which the page
* has will be completely replaced by the value being passed to the
* "text" field of the encoded form data
* @param title Title of the page to edit. Cannot be used together with pageid.
* @param summary Edit summary. Also section title when section=new and sectiontitle is not set
* @param text Holds the page content
* @param token A "csrf" token
*/
@FormUrlEncoded
@Headers("Cache-Control: no-cache")
@POST(Service.MW_API_PREFIX + "action=edit")
fun postEdit(
@Field("title") title: String,
@Field("summary") summary: String,
@Field("text") text: String,
// NOTE: This csrf shold always be sent as the last field of form data
@Field("token") token: String
): Observable<Edit>
/**
* This method posts such that the Content which the page
* has will be appended with the value being passed to the
* "appendText" field of the encoded form data
* @param title Title of the page to edit. Cannot be used together with pageid.
* @param summary Edit summary. Also section title when section=new and sectiontitle is not set
* @param appendText Text to add to the end of the page
* @param token A "csrf" token
*/
@FormUrlEncoded
@Headers("Cache-Control: no-cache")
@POST(Service.MW_API_PREFIX + "action=edit")
fun postAppendEdit(
@Field("title") title: String,
@Field("summary") summary: String,
@Field("appendtext") appendText: String,
@Field("token") token: String
): Observable<Edit>
/**
* This method posts such that the Content which the page
* has will be prepended with the value being passed to the
* "prependText" field of the encoded form data
* @param title Title of the page to edit. Cannot be used together with pageid.
* @param summary Edit summary. Also section title when section=new and sectiontitle is not set
* @param prependText Text to add to the beginning of the page
* @param token A "csrf" token
*/
@FormUrlEncoded
@Headers("Cache-Control: no-cache")
@POST(Service.MW_API_PREFIX + "action=edit")
fun postPrependEdit(
@Field("title") title: String,
@Field("summary") summary: String,
@Field("prependtext") prependText: String,
@Field("token") token: String
): Observable<Edit>
}

View file

@ -1,48 +0,0 @@
package fr.free.nrw.commons.actions;
import org.wikipedia.csrf.CsrfTokenClient;
import org.wikipedia.dataclient.Service;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import fr.free.nrw.commons.CommonsApplication;
import io.reactivex.Observable;
/**
* Facilitates the Wkikimedia Thanks api extension, as described in the
* api documentation: "The Thanks extension includes an API for sending thanks"
*
* In simple terms this class is used by a user to thank someone for adding
* contribution to the commons platform
*/
@Singleton
public class ThanksClient {
private final CsrfTokenClient csrfTokenClient;
private final Service service;
@Inject
public ThanksClient(@Named("commons-csrf") CsrfTokenClient csrfTokenClient,
@Named("commons-service") Service service) {
this.csrfTokenClient = csrfTokenClient;
this.service = service;
}
/**
* Handles the Thanking logic
* @param revisionID The revision ID you would like to thank someone for
* @return if thanks was successfully sent to intended recipient, returned as a boolean observable
*/
public Observable<Boolean> thank(long revisionId) {
try {
return service.thank(String.valueOf(revisionId), null,
csrfTokenClient.getTokenBlocking(),
CommonsApplication.getInstance().getUserAgent())
.map(mwQueryResponse -> mwQueryResponse.getSuccessVal() == 1);
} catch (Throwable throwable) {
return Observable.just(false);
}
}
}

View file

@ -0,0 +1,36 @@
package fr.free.nrw.commons.actions
import fr.free.nrw.commons.CommonsApplication
import fr.free.nrw.commons.di.NetworkingModule.NAMED_COMMONS_CSRF
import io.reactivex.Observable
import org.wikipedia.csrf.CsrfTokenClient
import org.wikipedia.dataclient.Service
import org.wikipedia.dataclient.mwapi.MwPostResponse
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Singleton
/**
* Client for the Wkikimedia Thanks API extension
* Thanks are used by a user to show gratitude to another user for their contributions
*/
@Singleton
class ThanksClient @Inject constructor(
@param:Named(NAMED_COMMONS_CSRF) private val csrfTokenClient: CsrfTokenClient,
@param:Named("commons-service") private val service: Service
) {
/**
* Thanks a user for a particular revision
* @param revisionId The revision ID the user would like to thank someone for
* @return if thanks was successfully sent to intended recipient
*/
fun thank(revisionId: Long): Observable<Boolean> {
return try {
service.thank(revisionId.toString(), null, csrfTokenClient.tokenBlocking, CommonsApplication.getInstance().userAgent)
.map { mwQueryResponse -> mwQueryResponse.successVal == 1 }
} catch (throwable: Throwable) {
Observable.just(false)
}
}
}

View file

@ -216,9 +216,8 @@ public class NetworkingModule {
@Provides
@Singleton
public PageEditClient provideCommonsPageEditClient(@Named(NAMED_COMMONS_CSRF) CsrfTokenClient csrfTokenClient,
@Named("commons-page-edit-service") PageEditInterface pageEditInterface,
@Named("commons-service") Service service) {
return new PageEditClient(csrfTokenClient, pageEditInterface, service);
@Named("commons-page-edit-service") PageEditInterface pageEditInterface) {
return new PageEditClient(csrfTokenClient, pageEditInterface);
}
@Provides

View file

@ -18,8 +18,6 @@ class PageEditClientTest {
private lateinit var csrfTokenClient: CsrfTokenClient
@Mock
private lateinit var pageEditInterface: PageEditInterface
@Mock
private lateinit var service: Service
private lateinit var pageEditClient: PageEditClient
@ -36,7 +34,7 @@ class PageEditClientTest {
@Throws(Exception::class)
fun setUp() {
MockitoAnnotations.initMocks(this)
pageEditClient = PageEditClient(csrfTokenClient, pageEditInterface, service)
pageEditClient = PageEditClient(csrfTokenClient, pageEditInterface)
}
/**