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

@ -64,4 +64,15 @@ protected boolean allowContinuousText() {
Please note that this may cause ability overlap. If multiple abilities can match the same command, the longest match will be taken. For example,
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.
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