Add parameters handler

This commit is contained in:
Andrea Cavalli 2020-10-16 12:18:53 +02:00
parent fe44f6480e
commit 8a3a5b7cee
10 changed files with 235 additions and 21 deletions

View File

@ -1,6 +1,5 @@
package it.tdlight.tdlibsession.td.easy;
import it.tdlight.common.utils.ScannerUtils;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationState;
import it.tdlight.jni.TdApi.AuthorizationStateClosed;
@ -8,11 +7,13 @@ import it.tdlight.jni.TdApi.AuthorizationStateClosing;
import it.tdlight.jni.TdApi.AuthorizationStateReady;
import it.tdlight.jni.TdApi.AuthorizationStateWaitCode;
import it.tdlight.jni.TdApi.AuthorizationStateWaitEncryptionKey;
import it.tdlight.jni.TdApi.AuthorizationStateWaitOtherDeviceConfirmation;
import it.tdlight.jni.TdApi.AuthorizationStateWaitPassword;
import it.tdlight.jni.TdApi.AuthorizationStateWaitPhoneNumber;
import it.tdlight.jni.TdApi.AuthorizationStateWaitRegistration;
import it.tdlight.jni.TdApi.AuthorizationStateWaitTdlibParameters;
import it.tdlight.jni.TdApi.CheckAuthenticationBotToken;
import it.tdlight.jni.TdApi.CheckAuthenticationCode;
import it.tdlight.jni.TdApi.CheckAuthenticationPassword;
import it.tdlight.jni.TdApi.CheckDatabaseEncryptionKey;
import it.tdlight.jni.TdApi.Error;
@ -38,6 +39,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.Objects;
import java.util.Set;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
@ -390,26 +392,67 @@ public class AsyncTdEasy {
logger.info("Telegram Terms of Service:\n" + authorizationStateWaitRegistration.termsOfService.text.text);
}
while (registerUser.firstName == null || registerUser.firstName.length() <= 0
|| registerUser.firstName.length() > 64 || registerUser.firstName.isBlank()) {
registerUser.firstName = ScannerUtils.askParameter(this.logName, "Enter First Name").trim();
}
while (registerUser.lastName == null || registerUser.firstName.length() > 64) {
registerUser.lastName = ScannerUtils.askParameter(this.logName, "Enter Last Name").trim();
}
return MonoUtils.thenOrError(sendDirectly(registerUser));
return Mono
.from(settings)
.map(TdEasySettings::getParameterRequestHandler)
.flatMap(handler -> {
return handler
.onParameterRequest(Parameter.ASK_FIRST_NAME, new ParameterInfoEmpty())
.filter(Objects::nonNull)
.map(String::trim)
.filter(firstName -> !firstName.isBlank() && firstName.length() <= 64 && firstName.length() > 0)
.repeatWhen(s -> s.takeWhile(n -> n == 0))
.last()
.doOnNext(firstName -> registerUser.firstName = firstName)
.then(handler
.onParameterRequest(Parameter.ASK_LAST_NAME, new ParameterInfoEmpty())
.filter(Objects::nonNull)
.map(String::trim)
.filter(lastName -> lastName.length() <= 64)
.repeatWhen(s -> s.takeWhile(n -> n == 0))
.last()
.defaultIfEmpty("")
.doOnNext(lastName -> registerUser.lastName = lastName)
)
.thenReturn(handler);
})
.then(MonoUtils.thenOrError(sendDirectly(registerUser)));
case TdApi.AuthorizationStateWaitOtherDeviceConfirmation.CONSTRUCTOR:
var authorizationStateWaitOtherDeviceConfirmation = (AuthorizationStateWaitOtherDeviceConfirmation) obj;
return Mono
.from(settings)
.map(TdEasySettings::getParameterRequestHandler)
.flatMap(handler -> {
return handler.onParameterRequest(Parameter.NOTIFY_LINK,
new ParameterInfoNotifyLink(authorizationStateWaitOtherDeviceConfirmation.link)
);
});
case TdApi.AuthorizationStateWaitCode.CONSTRUCTOR:
var authorizationStateWaitCode = (AuthorizationStateWaitCode) obj;
return Mono
.from(settings)
.map(TdEasySettings::getParameterRequestHandler)
.flatMap(handler -> {
return handler.onParameterRequest(Parameter.ASK_CODE,
new ParameterInfoCode(authorizationStateWaitCode.codeInfo.phoneNumber,
authorizationStateWaitCode.codeInfo.nextType,
authorizationStateWaitCode.codeInfo.timeout,
authorizationStateWaitCode.codeInfo.type
)
);
})
.flatMap(code -> MonoUtils.thenOrError(sendDirectly(new CheckAuthenticationCode(code))));
case AuthorizationStateWaitPassword.CONSTRUCTOR:
var authorizationStateWaitPassword = (AuthorizationStateWaitPassword) obj;
String passwordMessage = "Password authorization of '" + this.logName + "':";
if (authorizationStateWaitPassword.passwordHint != null && !authorizationStateWaitPassword.passwordHint.isBlank()) {
passwordMessage += "\n\tHint: " + authorizationStateWaitPassword.passwordHint;
}
logger.info(passwordMessage);
var password = ScannerUtils.askParameter(this.logName, "Enter your password");
return MonoUtils.thenOrError(sendDirectly(new CheckAuthenticationPassword(password)));
return Mono
.from(settings)
.map(TdEasySettings::getParameterRequestHandler)
.flatMap(handler -> {
return handler.onParameterRequest(Parameter.ASK_PASSWORD,
new ParameterInfoPasswordHint(authorizationStateWaitPassword.passwordHint)
);
})
.flatMap(password -> MonoUtils.thenOrError(sendDirectly(new CheckAuthenticationPassword(password))));
case AuthorizationStateReady.CONSTRUCTOR: {
return Mono.empty();
}

View File

@ -0,0 +1,9 @@
package it.tdlight.tdlibsession.td.easy;
public enum Parameter {
ASK_FIRST_NAME,
ASK_LAST_NAME,
ASK_CODE,
ASK_PASSWORD,
NOTIFY_LINK
}

View File

@ -0,0 +1,5 @@
package it.tdlight.tdlibsession.td.easy;
public interface ParameterInfo {
}

View File

@ -0,0 +1,47 @@
package it.tdlight.tdlibsession.td.easy;
import it.tdlight.jni.TdApi.AuthenticationCodeType;
import java.util.StringJoiner;
public class ParameterInfoCode implements ParameterInfo {
private final String phoneNumber;
private final AuthenticationCodeType nextType;
private final int timeout;
private final AuthenticationCodeType type;
public ParameterInfoCode(String phoneNumber,
AuthenticationCodeType nextType,
int timeout,
AuthenticationCodeType type) {
this.phoneNumber = phoneNumber;
this.nextType = nextType;
this.timeout = timeout;
this.type = type;
}
public String getPhoneNumber() {
return phoneNumber;
}
public AuthenticationCodeType getNextType() {
return nextType;
}
public int getTimeout() {
return timeout;
}
public AuthenticationCodeType getType() {
return type;
}
@Override
public String toString() {
return new StringJoiner(", ", ParameterInfoCode.class.getSimpleName() + "[", "]")
.add("phoneNumber='" + phoneNumber + "'")
.add("nextType=" + nextType)
.add("timeout=" + timeout)
.add("type=" + type)
.toString();
}
}

View File

@ -0,0 +1,5 @@
package it.tdlight.tdlibsession.td.easy;
public class ParameterInfoEmpty implements ParameterInfo {
}

View File

@ -0,0 +1,13 @@
package it.tdlight.tdlibsession.td.easy;
public class ParameterInfoNotifyLink implements ParameterInfo {
private final String link;
public ParameterInfoNotifyLink(String link) {
this.link = link;
}
public String getLink() {
return link;
}
}

View File

@ -0,0 +1,13 @@
package it.tdlight.tdlibsession.td.easy;
public class ParameterInfoPasswordHint implements ParameterInfo {
private final String hint;
public ParameterInfoPasswordHint(String hint) {
this.hint = hint;
}
public String getHint() {
return hint;
}
}

View File

@ -0,0 +1,7 @@
package it.tdlight.tdlibsession.td.easy;
import reactor.core.publisher.Mono;
public interface ParameterRequestHandler {
Mono<String> onParameterRequest(Parameter parameter, ParameterInfo parameterInfo);
}

View File

@ -0,0 +1,47 @@
package it.tdlight.tdlibsession.td.easy;
import it.tdlight.common.utils.ScannerUtils;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
public class ScannerParameterRequestHandler implements ParameterRequestHandler {
private final String botName;
public ScannerParameterRequestHandler(String botName) {
this.botName = botName;
}
@Override
public Mono<String> onParameterRequest(Parameter parameter, ParameterInfo parameterInfo) {
return Mono.fromCallable(() -> {
String question;
boolean trim = false;
switch (parameter) {
case ASK_FIRST_NAME: question = "Enter first name"; trim = true; break;
case ASK_LAST_NAME: question = "Enter last name"; trim = true; break;
case ASK_CODE: question = "Enter authentication code"; trim = true; break;
case ASK_PASSWORD:
question = "Enter your password";
String passwordMessage = "Password authorization of '" + this.botName + "':";
String hint = ((ParameterInfoPasswordHint) parameterInfo).getHint();
if (hint != null && !hint.isBlank()) {
passwordMessage += "\n\tHint: " + hint;
}
System.out.println(passwordMessage);
break;
case NOTIFY_LINK:
System.out.println("Please confirm this login link on another device: "
+ ((ParameterInfoNotifyLink) parameterInfo).getLink());
return "";
default: question = parameter.toString(); break;
}
var result = ScannerUtils.askParameter(this.botName, question);
if (trim) {
return result.trim();
} else {
return result;
}
}).subscribeOn(Schedulers.boundedElastic());
}
}

View File

@ -20,6 +20,7 @@ public class TdEasySettings {
public final boolean ignoreFileNames;
private final Long phoneNumber;
private final String botToken;
private final ParameterRequestHandler parameterRequestHandler;
public TdEasySettings(boolean useTestDc,
String databaseDirectory,
@ -36,7 +37,8 @@ public class TdEasySettings {
boolean enableStorageOptimizer,
boolean ignoreFileNames,
@Nullable Long phoneNumber,
@Nullable String botToken) {
@Nullable String botToken,
@Nullable ParameterRequestHandler parameterRequestHandler) {
this.useTestDc = useTestDc;
this.databaseDirectory = databaseDirectory;
this.filesDirectory = filesDirectory;
@ -56,6 +58,14 @@ public class TdEasySettings {
if ((phoneNumber == null) == (botToken == null)) {
throw new IllegalArgumentException("You must set a phone number or a bot token");
}
if (parameterRequestHandler == null) {
if (botToken != null) {
parameterRequestHandler = new ScannerParameterRequestHandler("bot_" + botToken.split(":")[0]);
} else {
parameterRequestHandler = new ScannerParameterRequestHandler("+" + phoneNumber);
}
}
this.parameterRequestHandler = parameterRequestHandler;
}
public boolean isPhoneNumberSet() {
@ -74,6 +84,10 @@ public class TdEasySettings {
return Objects.requireNonNull(botToken, "You must set a bot token");
}
public ParameterRequestHandler getParameterRequestHandler() {
return Objects.requireNonNull(parameterRequestHandler, "You must set a parameter request handler");
}
public static Builder newBuilder() {
return new Builder();
}
@ -98,6 +112,7 @@ public class TdEasySettings {
private Long phoneNumber = null;
@Nullable
private String botToken = null;
private ParameterRequestHandler parameterRequestHandler;
private Builder() {
@ -239,6 +254,15 @@ public class TdEasySettings {
return this;
}
public Builder setParameterRequestHandler(ParameterRequestHandler parameterRequestHandler) {
this.parameterRequestHandler = parameterRequestHandler;
return this;
}
public ParameterRequestHandler getParameterRequestHandler() {
return parameterRequestHandler;
}
public TdEasySettings build() {
return new TdEasySettings(useTestDc,
databaseDirectory,
@ -255,7 +279,8 @@ public class TdEasySettings {
enableStorageOptimizer,
ignoreFileNames,
phoneNumber,
botToken
botToken,
parameterRequestHandler
);
}
}