Merge pull request #812 from christianblos/feature/lazy-load-abilities

Feature/lazy load abilities
This commit is contained in:
Ruben Bermudez 2020-10-23 00:25:46 +01:00 committed by GitHub
commit aa030fa148
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 166 additions and 140 deletions

View File

@ -65,3 +65,14 @@ Please note that this may cause ability overlap. If multiple abilities can match
if you have two abilities `do` and `do1`, the command `/do1` will trigger the `do1` ability.
## Statistics
AbilityBot can accrue basic statistics about the usage of your abilities and replies. Simply `enableStats()` on an Ability builder or `enableStats(<name>)` on replies to activate this feature. Once activated, you may call `/stats` and the bot will print a basic list of statistics. At the moment, AbilityBot only tracks hits. In the future, this will be enhanced to track more stats.
## Execute code on bot registration
If you want to execute custom logic to initialize your bot, but you can't do it in the constructor,
you can override the `onRegister()` method:
```
@Override
public void onRegister() {
super.onRegister();
// Execute custom initialize logic here
}
```

View File

@ -104,6 +104,8 @@ public class ExampleBotTest {
public void setUp() {
// Create your bot
bot = new ExampleBot();
// Call onRegister() to initialize abilities etc.
bot.onRegister();
// Create a new sender as a mock
silent = mock(SilentSender.class);
// Set your bot silent sender to the mocked sender
@ -156,6 +158,7 @@ public class ExampleBotTest {
// Offline instance will get deleted at JVM shutdown
db = MapDBContext.offlineInstance("test");
bot = new ExampleBot(db);
bot.onRegister();
...
}
@ -180,6 +183,7 @@ public class ExampleBotTest {
@Before
public void setUp() {
bot = new ExampleBot(db);
bot.onRegister();
sender = mock(MessageSender.class);
SilentSender silent = new SilentSender(sender);
// Create setter in your bot

View File

@ -18,45 +18,45 @@ import static org.telegram.abilitybots.api.db.MapDBContext.onlineInstance;
* @author Abbas Abou Daya
*/
public abstract class AbilityBot extends BaseAbilityBot implements LongPollingBot {
protected AbilityBot(String botToken, String botUsername, DBContext db, AbilityToggle toggle, DefaultBotOptions botOptions) {
super(botToken, botUsername, db, toggle, botOptions);
}
protected AbilityBot(String botToken, String botUsername, DBContext db, AbilityToggle toggle, DefaultBotOptions botOptions) {
super(botToken, botUsername, db, toggle, botOptions);
}
protected AbilityBot(String botToken, String botUsername, AbilityToggle toggle, DefaultBotOptions options) {
this(botToken, botUsername, onlineInstance(botUsername), toggle, options);
}
protected AbilityBot(String botToken, String botUsername, AbilityToggle toggle, DefaultBotOptions options) {
this(botToken, botUsername, onlineInstance(botUsername), toggle, options);
}
protected AbilityBot(String botToken, String botUsername, DBContext db, AbilityToggle toggle) {
this(botToken, botUsername, db, toggle, new DefaultBotOptions());
}
protected AbilityBot(String botToken, String botUsername, DBContext db, AbilityToggle toggle) {
this(botToken, botUsername, db, toggle, new DefaultBotOptions());
}
protected AbilityBot(String botToken, String botUsername, DBContext db, DefaultBotOptions options) {
this(botToken, botUsername, db, new DefaultToggle(), options);
}
protected AbilityBot(String botToken, String botUsername, DBContext db, DefaultBotOptions options) {
this(botToken, botUsername, db, new DefaultToggle(), options);
}
protected AbilityBot(String botToken, String botUsername, DefaultBotOptions botOptions) {
this(botToken, botUsername, onlineInstance(botUsername), botOptions);
}
protected AbilityBot(String botToken, String botUsername, DefaultBotOptions botOptions) {
this(botToken, botUsername, onlineInstance(botUsername), botOptions);
}
protected AbilityBot(String botToken, String botUsername, AbilityToggle toggle) {
this(botToken, botUsername, onlineInstance(botUsername), toggle);
}
protected AbilityBot(String botToken, String botUsername, AbilityToggle toggle) {
this(botToken, botUsername, onlineInstance(botUsername), toggle);
}
protected AbilityBot(String botToken, String botUsername, DBContext db) {
this(botToken, botUsername, db, new DefaultToggle());
}
protected AbilityBot(String botToken, String botUsername, DBContext db) {
this(botToken, botUsername, db, new DefaultToggle());
}
protected AbilityBot(String botToken, String botUsername) {
this(botToken, botUsername, onlineInstance(botUsername));
}
protected AbilityBot(String botToken, String botUsername) {
this(botToken, botUsername, onlineInstance(botUsername));
}
@Override
public void onUpdateReceived(Update update) {
super.onUpdateReceived(update);
}
@Override
public void onUpdateReceived(Update update) {
super.onUpdateReceived(update);
}
@Override
public void clearWebhook() throws TelegramApiRequestException {
WebhookUtils.clearWebhook(this);
}
@Override
public void clearWebhook() throws TelegramApiRequestException {
WebhookUtils.clearWebhook(this);
}
}

View File

@ -21,54 +21,54 @@ import static org.telegram.abilitybots.api.db.MapDBContext.onlineInstance;
@SuppressWarnings("WeakerAccess")
public abstract class AbilityWebhookBot extends BaseAbilityBot implements WebhookBot {
private final String botPath;
private final String botPath;
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, DBContext db, AbilityToggle toggle, DefaultBotOptions botOptions) {
super(botToken, botUsername, db, toggle, botOptions);
this.botPath = botPath;
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, DBContext db, AbilityToggle toggle, DefaultBotOptions botOptions) {
super(botToken, botUsername, db, toggle, botOptions);
this.botPath = botPath;
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, AbilityToggle toggle, DefaultBotOptions options) {
this(botToken, botUsername, botPath, onlineInstance(botUsername), toggle, options);
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, AbilityToggle toggle, DefaultBotOptions options) {
this(botToken, botUsername, botPath, onlineInstance(botUsername), toggle, options);
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, DBContext db, AbilityToggle toggle) {
this(botToken, botUsername, botPath, db, toggle, new DefaultBotOptions());
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, DBContext db, AbilityToggle toggle) {
this(botToken, botUsername, botPath, db, toggle, new DefaultBotOptions());
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, DBContext db, DefaultBotOptions options) {
this(botToken, botUsername, botPath, db, new DefaultToggle(), options);
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, DBContext db, DefaultBotOptions options) {
this(botToken, botUsername, botPath, db, new DefaultToggle(), options);
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, DefaultBotOptions botOptions) {
this(botToken, botUsername, botPath, onlineInstance(botUsername), botOptions);
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, DefaultBotOptions botOptions) {
this(botToken, botUsername, botPath, onlineInstance(botUsername), botOptions);
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, AbilityToggle toggle) {
this(botToken, botUsername, botPath, onlineInstance(botUsername), toggle);
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, AbilityToggle toggle) {
this(botToken, botUsername, botPath, onlineInstance(botUsername), toggle);
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, DBContext db) {
this(botToken, botUsername, botPath, db, new DefaultToggle());
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath, DBContext db) {
this(botToken, botUsername, botPath, db, new DefaultToggle());
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath) {
this(botToken, botUsername, botPath, onlineInstance(botUsername));
}
protected AbilityWebhookBot(String botToken, String botUsername, String botPath) {
this(botToken, botUsername, botPath, onlineInstance(botUsername));
}
@Override
public BotApiMethod onWebhookUpdateReceived(Update update) {
super.onUpdateReceived(update);
return null;
}
@Override
public BotApiMethod onWebhookUpdateReceived(Update update) {
super.onUpdateReceived(update);
return null;
}
@Override
public void setWebhook(String url, String publicCertificatePath) throws TelegramApiRequestException {
WebhookUtils.setWebhook(this, url, publicCertificatePath);
}
@Override
public void setWebhook(String url, String publicCertificatePath) throws TelegramApiRequestException {
WebhookUtils.setWebhook(this, url, publicCertificatePath);
}
@Override
public String getBotPath() {
return botPath;
}
@Override
public String getBotPath() {
return botPath;
}
}

View File

@ -123,7 +123,9 @@ public abstract class BaseAbilityBot extends DefaultAbsSender implements Ability
this.toggle = toggle;
this.sender = new DefaultSender(this);
silent = new SilentSender(sender);
}
public void onRegister() {
registerAbilities();
initStats();
}

View File

@ -33,6 +33,7 @@ class AbilityBotI18nTest {
void setUp() {
db = offlineInstance("db");
bot = new NoPublicCommandsBot(EMPTY, EMPTY, db);
bot.onRegister();
defaultAbs = new DefaultAbilities(bot);
sender = mock(MessageSender.class);

View File

@ -71,6 +71,7 @@ public class AbilityBotTest {
void setUp() {
db = offlineInstance("db");
bot = new DefaultBot(EMPTY, EMPTY, db);
bot.onRegister();
defaultAbs = new DefaultAbilities(bot);
sender = mock(MessageSender.class);

View File

@ -33,6 +33,7 @@ public class ContinuousTextTest {
void setUp() {
db = offlineInstance("db");
bot = new ContinuousTextBot(EMPTY, EMPTY, db);
bot.onRegister();
silent = mock(SilentSender.class);
bot.silent = silent;
}

View File

@ -19,6 +19,7 @@ class ExtensionTest {
@BeforeEach
void setUp() {
bot = new ExtensionUsingBot();
bot.onRegister();
}
@AfterEach

View File

@ -39,6 +39,7 @@ public class ReplyFlowTest {
void setUp() {
db = offlineInstance("db");
bot = new ReplyFlowBot(EMPTY, EMPTY, db);
bot.onRegister();
sender = mock(MessageSender.class);
silent = mock(SilentSender.class);

View File

@ -26,6 +26,7 @@ public class BareboneToggleTest {
db = offlineInstance("db");
toggle = new BareboneToggle();
bareboneBot = new DefaultBot(EMPTY, EMPTY, db, toggle);
bareboneBot.onRegister();
defaultAbs = new DefaultAbilities(bareboneBot);
}

View File

@ -1,7 +1,6 @@
package org.telegram.abilitybots.api.toggle;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.telegram.abilitybots.api.bot.DefaultAbilities;
@ -18,12 +17,10 @@ class CustomToggleTest {
private DBContext db;
private AbilityToggle toggle;
private DefaultBot customBot;
private DefaultAbilities defaultAbs;
@BeforeEach
void setUp() {
db = offlineInstance("db");
defaultAbs = new DefaultAbilities(customBot);
}
@AfterEach
@ -36,6 +33,7 @@ class CustomToggleTest {
public void canTurnOffAbilities() {
toggle = new CustomToggle().turnOff(DefaultAbilities.CLAIM);
customBot = new DefaultBot(EMPTY, EMPTY, db, toggle);
customBot.onRegister();
assertFalse(customBot.abilities().containsKey(DefaultAbilities.CLAIM));
}
@ -44,6 +42,7 @@ class CustomToggleTest {
String targetName = DefaultAbilities.CLAIM + "1toggle";
toggle = new CustomToggle().toggle(DefaultAbilities.CLAIM, targetName);
customBot = new DefaultBot(EMPTY, EMPTY, db, toggle);
customBot.onRegister();
assertTrue(customBot.abilities().containsKey(targetName));
}

View File

@ -3,7 +3,6 @@ package org.telegram.abilitybots.api.toggle;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.telegram.abilitybots.api.bot.DefaultAbilities;
import org.telegram.abilitybots.api.bot.DefaultBot;
import org.telegram.abilitybots.api.db.DBContext;
import org.telegram.abilitybots.api.objects.Ability;
@ -18,52 +17,53 @@ import static org.telegram.abilitybots.api.bot.DefaultAbilities.*;
import static org.telegram.abilitybots.api.db.MapDBContext.offlineInstance;
class DefaultToggleTest {
private DBContext db;
private AbilityToggle toggle;
private DefaultBot defaultBot;
private DefaultAbilities defaultAbs;
private DBContext db;
private AbilityToggle toggle;
private DefaultBot defaultBot;
@BeforeEach
void setUp() {
db = offlineInstance("db");
defaultAbs = new DefaultAbilities(defaultBot);
}
@BeforeEach
void setUp() {
db = offlineInstance("db");
}
@AfterEach
void tearDown() throws IOException {
db.clear();
db.close();
}
@AfterEach
void tearDown() throws IOException {
db.clear();
db.close();
}
@Test
public void claimsEveryAbilityIsOn() {
Ability random = DefaultBot.getDefaultBuilder()
.name("randomsomethingrandom").build();
toggle = new DefaultToggle();
defaultBot = new DefaultBot(EMPTY, EMPTY, db, toggle);
@Test
public void claimsEveryAbilityIsOn() {
Ability random = DefaultBot.getDefaultBuilder()
.name("randomsomethingrandom").build();
toggle = new DefaultToggle();
defaultBot = new DefaultBot(EMPTY, EMPTY, db, toggle);
defaultBot.onRegister();
assertFalse(toggle.isOff(random));
}
assertFalse(toggle.isOff(random));
}
@Test
public void passedSameAbilityRefOnProcess() {
Ability random = DefaultBot.getDefaultBuilder()
.name("randomsomethingrandom").build();
toggle = new DefaultToggle();
defaultBot = new DefaultBot(EMPTY, EMPTY, db, toggle);
@Test
public void passedSameAbilityRefOnProcess() {
Ability random = DefaultBot.getDefaultBuilder()
.name("randomsomethingrandom").build();
toggle = new DefaultToggle();
defaultBot = new DefaultBot(EMPTY, EMPTY, db, toggle);
defaultBot.onRegister();
assertSame(random, toggle.processAbility(random), "Toggle returned a different ability");
}
assertSame(random, toggle.processAbility(random), "Toggle returned a different ability");
}
@Test
public void allAbilitiesAreRegistered() {
toggle = new DefaultToggle();
defaultBot = new DefaultBot(EMPTY, EMPTY, db, toggle);
Set<String> defaultNames = newHashSet(
CLAIM, BAN, UNBAN,
PROMOTE, DEMOTE, RECOVER,
BACKUP, REPORT, COMMANDS);
@Test
public void allAbilitiesAreRegistered() {
toggle = new DefaultToggle();
defaultBot = new DefaultBot(EMPTY, EMPTY, db, toggle);
defaultBot.onRegister();
Set<String> defaultNames = newHashSet(
CLAIM, BAN, UNBAN,
PROMOTE, DEMOTE, RECOVER,
BACKUP, REPORT, COMMANDS);
assertTrue(defaultBot.abilities().keySet().containsAll(defaultNames), "Toggle returned a different ability");
}
assertTrue(defaultBot.abilities().keySet().containsAll(defaultNames), "Toggle returned a different ability");
}
}

View File

@ -117,6 +117,7 @@ public class TelegramBotsApi {
* @param bot the bot to register
*/
public BotSession registerBot(LongPollingBot bot) throws TelegramApiRequestException {
bot.onRegister();
bot.clearWebhook();
BotSession session = ApiContext.getInstance(BotSession.class);
session.setToken(bot.getBotToken());
@ -132,6 +133,7 @@ public class TelegramBotsApi {
*/
public void registerBot(WebhookBot bot) throws TelegramApiRequestException {
if (useWebhook) {
bot.onRegister();
webhook.registerWebhook(bot);
bot.setWebhook(externalUrl + bot.getBotPath(), pathToCertificate);
}

View File

@ -11,7 +11,7 @@ import java.util.List;
* @brief Callback to handle updates.
* @date 20 of June of 2015
*/
public interface LongPollingBot {
public interface LongPollingBot extends TelegramBot {
/**
* This method is called when receiving updates via GetUpdates method
* @param update Update received
@ -27,16 +27,6 @@ public interface LongPollingBot {
updates.forEach(this::onUpdateReceived);
}
/**
* Return bot username of this bot
*/
String getBotUsername();
/**
* Return bot token to access Telegram API
*/
String getBotToken();
/**
* Gets options for current bot
* @return BotOptions object with options information

View File

@ -0,0 +1,24 @@
package org.telegram.telegrambots.meta.generics;
/**
* Main interface for telegram bots.
*/
public interface TelegramBot {
/**
* Return username of this bot
*/
String getBotUsername();
/**
* Return bot token to access Telegram API
*/
String getBotToken();
/**
* Is called when bot gets registered
*/
default void onRegister() {
}
}

View File

@ -10,25 +10,13 @@ import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
* @brief Callback to handle updates.
* @date 20 of June of 2015
*/
public interface WebhookBot {
public interface WebhookBot extends TelegramBot {
/**
* This method is called when receiving updates via webhook
* @param update Update received
*/
BotApiMethod onWebhookUpdateReceived(Update update);
/**
* Gets bot username of this bot
* @return Bot username
*/
String getBotUsername();
/**
* Gets bot token to access Telegram API
* @return Bot token
*/
String getBotToken();
/**
* Execute setWebhook method to set up the url of the webhook
* @param url Url for the webhook