#3 fixed - implemented help opportunity + fex bash.org quoter + refactoring

pull/6/head
bvn13 2019-03-15 23:48:49 +03:00
parent 7854aec055
commit 77712be97c
22 changed files with 326 additions and 520 deletions

View File

@ -6,7 +6,7 @@
<groupId>ru.bvn13</groupId> <groupId>ru.bvn13</groupId>
<artifactId>jircbot</artifactId> <artifactId>jircbot</artifactId>
<version>${bot.version}</version> <version>${jircbot.version}</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<parent> <parent>
@ -18,7 +18,7 @@
<properties> <properties>
<bot.version>2.0.8</bot.version> <bot.version>2.1.0</bot.version>
<java.version>1.8</java.version> <java.version>1.8</java.version>

View File

@ -2,8 +2,6 @@ package ru.bvn13.jircbot;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import ru.bvn13.jircbot.bot.JircBot;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -11,10 +9,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
public class MainApp { public class MainApp {
private static final Logger logger = LoggerFactory.getLogger(MainApp.class); private static final Logger logger = LoggerFactory.getLogger(MainApp.class);
@Autowired
private JircBot bot;
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(MainApp.class, args); SpringApplication.run(MainApp.class, args);
logger.info("==============> STARTING <=============="); logger.info("==============> STARTING <==============");

View File

@ -1,7 +1,6 @@
package ru.bvn13.jircbot.bot; package ru.bvn13.jircbot.bot;
import lombok.Getter;
import org.pircbotx.Configuration; import org.pircbotx.Configuration;
import org.pircbotx.MultiBotManager; import org.pircbotx.MultiBotManager;
import org.pircbotx.PircBotX; import org.pircbotx.PircBotX;
@ -14,7 +13,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.bvn13.jircbot.services.YandexSearchService;
import ru.bvn13.jircbot.config.JircBotConfiguration; import ru.bvn13.jircbot.config.JircBotConfiguration;
import ru.bvn13.jircbot.listeners.*; import ru.bvn13.jircbot.listeners.*;
import ru.bvn13.jircbot.listeners.advices.AdviceListener; import ru.bvn13.jircbot.listeners.advices.AdviceListener;
@ -38,9 +36,9 @@ public class JircBot extends ListenerAdapter {
private static Logger logger = LoggerFactory.getLogger(JircBot.class); private static Logger logger = LoggerFactory.getLogger(JircBot.class);
@Value("${bot.version}") @Value("${jircbot.version}")
private String version; private String version;
public String getVersion() { private String getVersion() {
return version == null ? "" : version; return version == null ? "" : version;
} }
@ -49,9 +47,6 @@ public class JircBot extends ListenerAdapter {
private Map<String, PircBotX> bots = new HashMap<>(); private Map<String, PircBotX> bots = new HashMap<>();
@Autowired
private YandexSearchService yandexSearchService;
@Autowired @Autowired
public JircBot(JircBotConfiguration config) { public JircBot(JircBotConfiguration config) {
@ -63,64 +58,37 @@ public class JircBot extends ListenerAdapter {
private MultiBotManager manager = new MultiBotManager(); private MultiBotManager manager = new MultiBotManager();
@Autowired
private PingPongListener pingPongListener; private PingPongListener pingPongListener;
@Autowired
private CalculatorListener calculatorListener; private CalculatorListener calculatorListener;
@Autowired
private RegexCheckerListener regexCheckerListener; private RegexCheckerListener regexCheckerListener;
@Autowired
private AdviceListener adviceListener; private AdviceListener adviceListener;
@Autowired
private QuizListener quizListener; private QuizListener quizListener;
@Autowired
private BashOrgListener bashOrgListener; private BashOrgListener bashOrgListener;
@Autowired
private AutoRejoinListener autoRejoinListener; private AutoRejoinListener autoRejoinListener;
@Autowired
private DeferredMessagesListener deferredMessagesListener; private DeferredMessagesListener deferredMessagesListener;
@Autowired
private LinkPreviewListener linkPreviewListener; private LinkPreviewListener linkPreviewListener;
@Autowired
private HelloOnJoinListener helloOnJoinListener; private HelloOnJoinListener helloOnJoinListener;
@Autowired
private GrammarCorrectorListener grammarCorrectorListener; private GrammarCorrectorListener grammarCorrectorListener;
private HelpListener helpListener;
@Autowired
private GoogleSearchListener googleSearchListener;
@Autowired
private DuckDuckGoSearchListener duckDuckGoSearchListener; private DuckDuckGoSearchListener duckDuckGoSearchListener;
@Autowired
private LoggerListener loggerListener; private LoggerListener loggerListener;
@Autowired
private AdminListener adminListener; private AdminListener adminListener;
@Autowired
private StatisticsListener statisticsListener; private StatisticsListener statisticsListener;
@PostConstruct @PostConstruct
public void postConstruct() { public void postConstruct() {
logger.warn("VERSION: "+version); logger.warn("VERSION: "+version);
this.executorService = Executors.newScheduledThreadPool(10); this.executorService = Executors.newScheduledThreadPool(10);
this.executorService.schedule(new Runnable() { this.executorService.schedule(() -> {
@Override initBots();
public void run() { startBots();
initBots();
startBots();
}
}, 5, TimeUnit.SECONDS); }, 5, TimeUnit.SECONDS);
this.executorService.scheduleAtFixedRate(new Runnable() { this.executorService.scheduleAtFixedRate(() -> {
@Override logger.debug("check");
public void run() { checkBots();
logger.debug("check");
checkBots();
}
}, 15, 5, TimeUnit.SECONDS); }, 15, 5, TimeUnit.SECONDS);
} }
@ -162,14 +130,10 @@ public class JircBot extends ListenerAdapter {
.addListener(linkPreviewListener) .addListener(linkPreviewListener)
.addListener(helloOnJoinListener) .addListener(helloOnJoinListener)
.addListener(grammarCorrectorListener) .addListener(grammarCorrectorListener)
//.addListener(googleSearchListener) .addListener(helpListener)
.addListener(duckDuckGoSearchListener) .addListener(duckDuckGoSearchListener)
.addListener(loggerListener) .addListener(loggerListener)
// not tested
//.addListener(new GoogleDoodleListener(this.config))
//.addListener(new YandexSearchListener(this.config, this.yandexSearchService))
.setServers(servers) .setServers(servers)
.setAutoReconnect(true) .setAutoReconnect(true)
.addAutoJoinChannels(c.getChannelsNames()); .addAutoJoinChannels(c.getChannelsNames());
@ -235,4 +199,85 @@ public class JircBot extends ListenerAdapter {
return ""+d[d.length-2]+"."+d[d.length-1]; return ""+d[d.length-2]+"."+d[d.length-1];
} }
//*************************************************
@Autowired
public void setPingPongListener(PingPongListener pingPongListener) {
this.pingPongListener = pingPongListener;
}
@Autowired
public void setCalculatorListener(CalculatorListener calculatorListener) {
this.calculatorListener = calculatorListener;
}
@Autowired
public void setRegexCheckerListener(RegexCheckerListener regexCheckerListener) {
this.regexCheckerListener = regexCheckerListener;
}
@Autowired
public void setAdviceListener(AdviceListener adviceListener) {
this.adviceListener = adviceListener;
}
@Autowired
public void setQuizListener(QuizListener quizListener) {
this.quizListener = quizListener;
}
@Autowired
public void setBashOrgListener(BashOrgListener bashOrgListener) {
this.bashOrgListener = bashOrgListener;
}
@Autowired
public void setAutoRejoinListener(AutoRejoinListener autoRejoinListener) {
this.autoRejoinListener = autoRejoinListener;
}
@Autowired
public void setDeferredMessagesListener(DeferredMessagesListener deferredMessagesListener) {
this.deferredMessagesListener = deferredMessagesListener;
}
@Autowired
public void setLinkPreviewListener(LinkPreviewListener linkPreviewListener) {
this.linkPreviewListener = linkPreviewListener;
}
@Autowired
public void setHelloOnJoinListener(HelloOnJoinListener helloOnJoinListener) {
this.helloOnJoinListener = helloOnJoinListener;
}
@Autowired
public void setGrammarCorrectorListener(GrammarCorrectorListener grammarCorrectorListener) {
this.grammarCorrectorListener = grammarCorrectorListener;
}
@Autowired
public void setHelpListener(HelpListener helpListener) {
this.helpListener = helpListener;
}
@Autowired
public void setDuckDuckGoSearchListener(DuckDuckGoSearchListener duckDuckGoSearchListener) {
this.duckDuckGoSearchListener = duckDuckGoSearchListener;
}
@Autowired
public void setLoggerListener(LoggerListener loggerListener) {
this.loggerListener = loggerListener;
}
@Autowired
public void setAdminListener(AdminListener adminListener) {
this.adminListener = adminListener;
}
@Autowired
public void setStatisticsListener(StatisticsListener statisticsListener) {
this.statisticsListener = statisticsListener;
}
} }

View File

@ -23,10 +23,13 @@ public class JircBotConfiguration {
private static Logger logger = LoggerFactory.getLogger(JircBotConfiguration.class); private static Logger logger = LoggerFactory.getLogger(JircBotConfiguration.class);
@Value("${jircbot.config}")
@Value("${config}")
private String configFileName; private String configFileName;
@Getter
@Value("${jircbot.url.main}")
private String mainUrl;
@Getter @Getter
private List<Config> connections = new ArrayList<>(); private List<Config> connections = new ArrayList<>();
@ -135,4 +138,5 @@ public class JircBotConfiguration {
return sets; return sets;
} }
} }

View File

@ -5,6 +5,8 @@ import org.modelmapper.internal.util.Lists;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
/** /**
* Created by bvn13 on 28.10.2018. * Created by bvn13 on 28.10.2018.
@ -29,4 +31,18 @@ public class DocumentationProvider {
return descriptors.getOrDefault(moduleName, null); return descriptors.getOrDefault(moduleName, null);
} }
public Optional<ListenerDescription.CommandDescription> findByCommand(final String command) {
AtomicReference<ListenerDescription.CommandDescription> description = new AtomicReference<>(null);
descriptors.forEach((name, dp) -> {
dp.getDescription().getCommandDescriptionOpt(command).ifPresent(description::set);
});
return Optional.ofNullable(description.get());
}
public String getAllCommands() {
return descriptors.values().stream().map(dp -> dp.getDescription().getCommandNamesJoined()).filter(s -> s != null && !s.isEmpty()).collect(Collectors.joining(","));
}
} }

View File

@ -7,6 +7,8 @@ import org.modelmapper.internal.util.Lists;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/** /**
* Created by bvn13 on 28.10.2018. * Created by bvn13 on 28.10.2018.
@ -54,14 +56,19 @@ public class ListenerDescription {
return this; return this;
} }
public String getCommandNamesJoined() {
return Lists.from(commandsDescription.keySet().iterator()).stream().sorted().collect(Collectors.joining(","));
}
public Optional<CommandDescription> getCommandDescriptionOpt(String command) {
return Optional.ofNullable(commandsDescription.getOrDefault(command, null));
}
public List<String> getCommandNames() { public List<String> getCommandNames() {
List<String> names = Lists.from(commandsDescription.keySet().iterator()); return Lists.from(commandsDescription.keySet().iterator());
names.sort(String.CASE_INSENSITIVE_ORDER);
return names;
} }
public CommandDescription getCommandDescription(String command) { public CommandDescription getCommandDescription(String command) {
return commandsDescription.getOrDefault(command, null); return commandsDescription.getOrDefault(command, null);
} }
} }

View File

@ -32,10 +32,8 @@ public class AdminListener extends ImprovedListenerAdapter implements Descriptio
private static final String COMMAND = "?"; private static final String COMMAND = "?";
@Autowired
private JircBotConfiguration configuration; private JircBotConfiguration configuration;
@Autowired
private ChannelSettingsService channelSettingsService; private ChannelSettingsService channelSettingsService;
@Autowired @Autowired
@ -386,4 +384,13 @@ public class AdminListener extends ImprovedListenerAdapter implements Descriptio
} }
} }
@Autowired
public void setConfiguration(JircBotConfiguration configuration) {
this.configuration = configuration;
}
@Autowired
public void setChannelSettingsService(ChannelSettingsService channelSettingsService) {
this.channelSettingsService = channelSettingsService;
}
} }

View File

@ -18,7 +18,6 @@ import ru.bvn13.jircbot.listeners.advices.AdviceEngine;
@Component @Component
public class AutoRejoinListener extends ImprovedListenerAdapter { public class AutoRejoinListener extends ImprovedListenerAdapter {
@Autowired
private ChannelSettingsService channelSettingsService; private ChannelSettingsService channelSettingsService;
private Boolean wasKicked = false; private Boolean wasKicked = false;
@ -56,4 +55,9 @@ public class AutoRejoinListener extends ImprovedListenerAdapter {
} }
} }
@Autowired
public void setChannelSettingsService(ChannelSettingsService channelSettingsService) {
this.channelSettingsService = channelSettingsService;
}
} }

View File

@ -18,6 +18,8 @@ import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static ru.bvn13.jircbot.documentation.ListenerDescription.CommandDescription; import static ru.bvn13.jircbot.documentation.ListenerDescription.CommandDescription;
@ -30,7 +32,8 @@ public class BashOrgListener extends ImprovedListenerAdapter implements Descript
private static final String COMMAND = "?bash"; private static final String COMMAND = "?bash";
private static final String USER_AGENT = "Mozilla/5.0"; private static final String USER_AGENT = "Mozilla/5.0";
@Autowired private static final Pattern PATTERN_CHARSET = Pattern.compile(".*charset=(.*)$");
private ChannelSettingsService channelSettingsService; private ChannelSettingsService channelSettingsService;
@Autowired @Autowired
@ -70,14 +73,14 @@ public class BashOrgListener extends ImprovedListenerAdapter implements Descript
try { try {
event.respond(getRandomBashQuote()); event.respond(getRandomBashQuote());
} catch (Exception e) { } catch (Exception e) {
event.respond("ОШИБКА: "+e.getMessage()); event.respond("ERROR: "+e.getMessage());
e.printStackTrace(); e.printStackTrace();
} }
} }
private String getDataFromConnection(HttpURLConnection con) throws Exception { private String getDataFromConnection(HttpURLConnection con) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(), "windows-1251")); BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine; String inputLine;
StringBuilder response = new StringBuilder(); StringBuilder response = new StringBuilder();
@ -89,13 +92,14 @@ public class BashOrgListener extends ImprovedListenerAdapter implements Descript
} }
private String getRandomBashQuote() throws Exception { private String getRandomBashQuote() throws Exception {
URL obj = new URL("http://bash.im/random"); URL obj = new URL("https://bash.im/random");
HttpURLConnection con = (HttpURLConnection) obj.openConnection(); HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET // optional default is GET
con.setRequestMethod("GET"); con.setRequestMethod("GET");
//add request header //add request header
con.setRequestProperty("Accept-Charset", "utf-8");
con.setRequestProperty("User-Agent", USER_AGENT); con.setRequestProperty("User-Agent", USER_AGENT);
//con.setRequestProperty("X-Requested-With", "XMLHttpRequest"); //con.setRequestProperty("X-Requested-With", "XMLHttpRequest");
@ -103,10 +107,17 @@ public class BashOrgListener extends ImprovedListenerAdapter implements Descript
if (responseCode != 200) { if (responseCode != 200) {
throw new Exception("Could not get a random quote!"); throw new Exception("Could not get a random quote!");
} }
String contentType = con.getContentType();
Matcher matcher = PATTERN_CHARSET.matcher(contentType);
String charset = "utf-8";
if (matcher.find()) {
charset = matcher.group(1);
}
String response = getDataFromConnection(con); String response = getDataFromConnection(con);
Document doc = Jsoup.parse(response); Document doc = Jsoup.parse(response);
Elements quotes = doc.select(".quote .text"); Elements quotes = doc.select("article.quote .quote__body");
if (quotes.size() == 0) { if (quotes.size() == 0) {
throw new Exception("Nothing was received from bash.org!"); throw new Exception("Nothing was received from bash.org!");
@ -114,9 +125,13 @@ public class BashOrgListener extends ImprovedListenerAdapter implements Descript
Element quote = quotes.get(0); Element quote = quotes.get(0);
return quote.text(); return quote.text().replace("\n", "");
} }
@Autowired
public void setChannelSettingsService(ChannelSettingsService channelSettingsService) {
this.channelSettingsService = channelSettingsService;
}
} }

View File

@ -32,10 +32,8 @@ public class DeferredMessagesListener extends ImprovedListenerAdapter implements
private static SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private static SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Autowired
private ChannelSettingsService channelSettingsService; private ChannelSettingsService channelSettingsService;
@Autowired
private DeferredMessageService deferredMessageService; private DeferredMessageService deferredMessageService;
@Autowired @Autowired
@ -160,4 +158,13 @@ public class DeferredMessagesListener extends ImprovedListenerAdapter implements
} }
@Autowired
public void setChannelSettingsService(ChannelSettingsService channelSettingsService) {
this.channelSettingsService = channelSettingsService;
}
@Autowired
public void setDeferredMessageService(DeferredMessageService deferredMessageService) {
this.deferredMessageService = deferredMessageService;
}
} }

View File

@ -26,10 +26,8 @@ public class DuckDuckGoSearchListener extends ImprovedListenerAdapter implements
private static final String COMMAND = "?s"; private static final String COMMAND = "?s";
@Autowired
private InternetAccessor internetAccessor; private InternetAccessor internetAccessor;
@Autowired
private ChannelSettingsService channelSettingsService; private ChannelSettingsService channelSettingsService;
@Autowired @Autowired
@ -95,4 +93,13 @@ public class DuckDuckGoSearchListener extends ImprovedListenerAdapter implements
} }
@Autowired
public void setInternetAccessor(InternetAccessor internetAccessor) {
this.internetAccessor = internetAccessor;
}
@Autowired
public void setChannelSettingsService(ChannelSettingsService channelSettingsService) {
this.channelSettingsService = channelSettingsService;
}
} }

View File

@ -1,118 +0,0 @@
package ru.bvn13.jircbot.listeners;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.pircbotx.hooks.events.MessageEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.bvn13.jircbot.bot.ImprovedListenerAdapter;
import ru.bvn13.jircbot.bot.JircBot;
import ru.bvn13.jircbot.database.services.ChannelSettingsService;
import ru.bvn13.jircbot.documentation.DescriptionProvided;
import ru.bvn13.jircbot.documentation.DocumentationProvider;
import ru.bvn13.jircbot.documentation.ListenerDescription;
import ru.bvn13.jircbot.services.InternetAccessor;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import static ru.bvn13.jircbot.documentation.ListenerDescription.CommandDescription;
/**
* Created by bvn13 on 06.02.2018.
*/
@Component
public class GoogleSearchListener extends ImprovedListenerAdapter implements DescriptionProvided {
private static final String COMMAND = "?gs";
@Autowired
private InternetAccessor internetAccessor;
@Autowired
private ChannelSettingsService channelSettingsService;
@Autowired
public GoogleSearchListener(DocumentationProvider documentationProvider) {
this.registerDescription(documentationProvider);
}
@Override
public ListenerDescription getDescription() {
return ListenerDescription.create()
.setModuleName("GoogleSearchListener")
.setModuleDescription("Make a search in Google for you")
.addCommand(CommandDescription.builder()
.command("gs")
.description("Search it")
.example("?gs [WHAT YOU WANT TO SEARCH]")
.build()
);
}
@Override
public void onMessage(final MessageEvent event) throws Exception {
super.onMessage(event);
if (!channelSettingsService.getChannelSettings(JircBot.extractServer(event.getBot().getServerHostname()), this.getChannelName(event)).getGoogleSearchEnabled()) {
return;
}
if (event.getUser() != null && event.getBot().getUserBot().getNick().equals(event.getUser().getNick())) {
return;
}
if (!event.getMessage().startsWith(COMMAND)) {
return;
}
String message = event.getMessage().replace(COMMAND, "").trim();
String result = search(message);
event.respond(result);
}
private String search(String phrase) throws UnsupportedEncodingException {
String encodedPhrase = URLEncoder.encode(phrase.replaceAll(" ", "+"), "utf-8");
String link = "https://google.ru/search?q="+encodedPhrase;
String queryPage = internetAccessor.retrieveContentByLink(link);
Document doc = Jsoup.parse(queryPage);
Elements searchResults = doc.select("#res #search #ires .g");
Element firstResult = searchResults.first();
Element descrElement = firstResult.select(".s .st").first();
String description = descrElement.text();
Element linkToRedirectPage = firstResult.select(".r a").first();
String linkTitle = linkToRedirectPage.text();
String redirectPage = internetAccessor.retrieveContentByLink("https://google.ru"+linkToRedirectPage.attr("href"));
String destinationUrl = null;
try {
Document redirectDoc = Jsoup.parse(redirectPage);
destinationUrl = redirectDoc.select("._jFe a").first().attr("href");
} catch (Exception e) {
try {
destinationUrl = internetAccessor.getLastUrl("https://google.ru"+linkToRedirectPage.attr("href"));
if (destinationUrl == null || destinationUrl.isEmpty()) {
destinationUrl = "https://google.ru"+linkToRedirectPage.attr("href");
}
} catch (Exception e1) {
destinationUrl = "https://google.ru"+linkToRedirectPage.attr("href");
}
}
return String.format("%s / %s / %s", URLDecoder.decode(destinationUrl, "utf-8"), linkTitle, description);
}
}

View File

@ -28,10 +28,8 @@ public class GrammarCorrectorListener extends ImprovedListenerAdapter {
private static SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private static SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Autowired
private ChannelSettingsService channelSettingsService; private ChannelSettingsService channelSettingsService;
@Autowired
private GrammarCorrectionService grammarCorrectionService; private GrammarCorrectionService grammarCorrectionService;
@ -133,4 +131,14 @@ public class GrammarCorrectorListener extends ImprovedListenerAdapter {
return "syntax: ?correct add <REGEX-formatted word> > <full correction> | ?correct remove <REGEX-formatted word> > <full correction> | ?correct show"; return "syntax: ?correct add <REGEX-formatted word> > <full correction> | ?correct remove <REGEX-formatted word> > <full correction> | ?correct show";
} }
@Autowired
public void setChannelSettingsService(ChannelSettingsService channelSettingsService) {
this.channelSettingsService = channelSettingsService;
}
@Autowired
public void setGrammarCorrectionService(GrammarCorrectionService grammarCorrectionService) {
this.grammarCorrectionService = grammarCorrectionService;
}
} }

View File

@ -20,9 +20,14 @@ import static ru.bvn13.jircbot.documentation.ListenerDescription.CommandDescript
@Component @Component
public class HelloOnJoinListener extends ImprovedListenerAdapter implements DescriptionProvided { public class HelloOnJoinListener extends ImprovedListenerAdapter implements DescriptionProvided {
@Autowired
private ChannelSettingsService channelSettingsService; private ChannelSettingsService channelSettingsService;
@Autowired
public HelloOnJoinListener(DocumentationProvider documentationProvider) {
registerDescription(documentationProvider);
}
@Override @Override
public void onJoin(final JoinEvent event) throws Exception { public void onJoin(final JoinEvent event) throws Exception {
@ -45,10 +50,6 @@ public class HelloOnJoinListener extends ImprovedListenerAdapter implements Desc
} }
} }
@Autowired
public HelloOnJoinListener(DocumentationProvider documentationProvider) {
registerDescription(documentationProvider);
}
@Override @Override
public ListenerDescription getDescription() { public ListenerDescription getDescription() {
@ -59,4 +60,8 @@ public class HelloOnJoinListener extends ImprovedListenerAdapter implements Desc
; ;
} }
@Autowired
public void setChannelSettingsService(ChannelSettingsService channelSettingsService) {
this.channelSettingsService = channelSettingsService;
}
} }

View File

@ -0,0 +1,90 @@
package ru.bvn13.jircbot.listeners;
import org.pircbotx.hooks.events.MessageEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.bvn13.jircbot.bot.ImprovedListenerAdapter;
import ru.bvn13.jircbot.config.JircBotConfiguration;
import ru.bvn13.jircbot.documentation.DocumentationProvider;
import ru.bvn13.jircbot.documentation.ListenerDescription;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/**
* Created by bvn13 on 15.03.2019.
*/
@Component
public class HelpListener extends ImprovedListenerAdapter {
private static final List<String> COMMAND = Arrays.asList("?help", "?h");
private JircBotConfiguration configuration;
private DocumentationProvider documentationProvider;
private String adviceToFolowMainUrl;
@PostConstruct
private void init() {
adviceToFolowMainUrl = String.format("see all docs: %s/docs", configuration.getMainUrl());
}
@Override
public void onMessage(MessageEvent event) throws Exception {
super.onMessage(event);
if (event.getUser() != null && event.getBot().getUserBot().getNick().equals(event.getUser().getNick())) {
return;
}
boolean isHelp = false;
String command = "";
for (String c : COMMAND) {
if (event.getMessage().startsWith(c)) {
isHelp = true;
command = c;
break;
}
}
if (!isHelp) {
return;
}
String message = event.getMessage().replace(command, "").trim();
if (message.isEmpty()) {
event.respond(adviceToFolowMainUrl);
} else {
answerWithHelp(event, message);
}
}
private void answerWithHelp(MessageEvent event, String message) {
String[] words = message.replace(" ", "").split(" ");
if (words.length > 1) {
event.respond(String.format("help syntax: ?help | ?help <COMMAND> | Commands: %s", documentationProvider.getAllCommands()));
} else {
Optional<ListenerDescription.CommandDescription> description = documentationProvider.findByCommand(words[0]);
if (description.isPresent()) {
ListenerDescription.CommandDescription d = description.get();
event.respond(String.format("COMMAND: %s, DESCRIPTION: %s, EXAMPLE: %s", d.getCommand(), d.getDescription(), d.getExample()));
} else {
event.respond(String.format("wrong command %s. %s%s", words[0], adviceToFolowMainUrl.substring(0, 1).toUpperCase(), adviceToFolowMainUrl.substring(1)));
}
}
}
@Autowired
public void setDocumentationProvider(DocumentationProvider documentationProvider) {
this.documentationProvider = documentationProvider;
}
@Autowired
public void setConfiguration(JircBotConfiguration configuration) {
this.configuration = configuration;
}
}

View File

@ -25,12 +25,10 @@ import static ru.bvn13.jircbot.documentation.ListenerDescription.CommandDescript
@Component @Component
public class LinkPreviewListener extends ImprovedListenerAdapter implements DescriptionProvided { public class LinkPreviewListener extends ImprovedListenerAdapter implements DescriptionProvided {
@Autowired
private InternetAccessor internetAccessor; private InternetAccessor internetAccessor;
private static final Pattern REGEX = Pattern.compile("(?i)(?:(?:https?|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))\\.?)(?::\\d{2,5})?(?:[/?#]\\S*)?"); private static final Pattern REGEX = Pattern.compile("(?i)(?:(?:https?|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))\\.?)(?::\\d{2,5})?(?:[/?#]\\S*)?");
@Autowired
private ChannelSettingsService channelSettingsService; private ChannelSettingsService channelSettingsService;
@Autowired @Autowired
@ -155,4 +153,14 @@ public class LinkPreviewListener extends ImprovedListenerAdapter implements Desc
} }
return null; return null;
} }
@Autowired
public void setInternetAccessor(InternetAccessor internetAccessor) {
this.internetAccessor = internetAccessor;
}
@Autowired
public void setChannelSettingsService(ChannelSettingsService channelSettingsService) {
this.channelSettingsService = channelSettingsService;
}
} }

View File

@ -25,10 +25,8 @@ import static ru.bvn13.jircbot.documentation.ListenerDescription.CommandDescript
public class LoggerListener extends ImprovedListenerAdapter implements DescriptionProvided { public class LoggerListener extends ImprovedListenerAdapter implements DescriptionProvided {
@Autowired
private ChannelSettingsService channelSettingsService; private ChannelSettingsService channelSettingsService;
@Autowired
private IrcMessageService ircMessageService; private IrcMessageService ircMessageService;
private Map<String, Set<String>> onlineUsers = new HashMap<>(); private Map<String, Set<String>> onlineUsers = new HashMap<>();
@ -198,4 +196,14 @@ public class LoggerListener extends ImprovedListenerAdapter implements Descripti
ircMessageService.save(msg); ircMessageService.save(msg);
} }
@Autowired
public void setChannelSettingsService(ChannelSettingsService channelSettingsService) {
this.channelSettingsService = channelSettingsService;
}
@Autowired
public void setIrcMessageService(IrcMessageService ircMessageService) {
this.ircMessageService = ircMessageService;
}
} }

View File

@ -26,7 +26,6 @@ public class RegexCheckerListener extends ImprovedListenerAdapter implements Des
private static final Map<String, Boolean> usersState = new HashMap<>(); private static final Map<String, Boolean> usersState = new HashMap<>();
@Autowired
private ChannelSettingsService channelSettingsService; private ChannelSettingsService channelSettingsService;
@Autowired @Autowired
@ -119,4 +118,8 @@ public class RegexCheckerListener extends ImprovedListenerAdapter implements Des
} }
@Autowired
public void setChannelSettingsService(ChannelSettingsService channelSettingsService) {
this.channelSettingsService = channelSettingsService;
}
} }

View File

@ -31,7 +31,6 @@ public class StatisticsListener extends ImprovedListenerAdapter implements Descr
Date dateStart; Date dateStart;
} }
@Autowired
private IrcMessageService ircMessageService; private IrcMessageService ircMessageService;
@Autowired @Autowired
@ -198,4 +197,9 @@ public class StatisticsListener extends ImprovedListenerAdapter implements Descr
private void sendHelp(MessageEvent event) { private void sendHelp(MessageEvent event) {
event.respond("syntax: ?stats [d(ay)|m(onth)|y(ear)|a(ll)] [all]"); event.respond("syntax: ?stats [d(ay)|m(onth)|y(ear)|a(ll)] [all]");
} }
@Autowired
public void setIrcMessageService(IrcMessageService ircMessageService) {
this.ircMessageService = ircMessageService;
}
} }

View File

@ -1,63 +0,0 @@
package ru.bvn13.jircbot.listeners;
import org.pircbotx.hooks.ListenerAdapter;
import org.pircbotx.hooks.types.GenericMessageEvent;
import ru.bvn13.jircbot.services.YandexSearchService;
import ru.bvn13.jircbot.config.JircBotConfiguration;
import ru.bvn13.jircbot.model.YandexSearchSettings;
import static ru.bvn13.jircbot.config.JircBotConfiguration.KEY_YANDEX_SEARCH;
public class YandexSearchListener extends ListenerAdapter {
private static final String COMMAND = "?search ";
private YandexSearchSettings config;
private YandexSearchService yandexSearchService;
public YandexSearchListener(JircBotConfiguration config, YandexSearchService yandexSearchService) {
this.config = (YandexSearchSettings) config.getListenersSettings().get(KEY_YANDEX_SEARCH);
this.yandexSearchService = yandexSearchService;
this.yandexSearchService.setKey(this.config.getKey());
this.yandexSearchService.setUser(this.config.getUser());
this.yandexSearchService.setUrl(this.config.getUrl());
}
@Override
public void onGenericMessage(final GenericMessageEvent event) throws Exception {
super.onGenericMessage(event);
if (event.getUser() != null && event.getBot().getUserBot().getNick().equals(event.getUser().getNick())) {
return;
}
if (!event.getMessage().startsWith(COMMAND)) {
return;
}
String message = event.getMessage().substring(COMMAND.length()).trim();
try {
final YandexSearchService.YaPage result = this.yandexSearchService.loadYaPage(message, 0);
int i = 0;
for (YandexSearchService.YaItem item : result.getYaItems()) {
if (i++ == 0) {
event.respond(String.format("%s - %s (%s)", item.getUrl(), item.getTitle(), item.getDescription()));
//event.respond("Next entries were sended privately.");
} else {
event.respondPrivateMessage(String.format("%d. %s - %s (%s)", (i - 1), item.getUrl(), item.getTitle(), item.getDescription()));
}
}
if (i == 0) {
event.respond("Not found");
}
} catch (Exception exp) {
exp.printStackTrace();
event.respond("ERROR has been occurred. Try again later.");
}
}
}

View File

@ -1,248 +0,0 @@
package ru.bvn13.jircbot.services;
import lombok.Getter;
import lombok.Setter;
import org.springframework.stereotype.Service;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
@Service
public class YandexSearchService {
public static final String ENC = "UTF-8";
public static final String AND = "&";
public static class YaPage {
public static final int ITEMS_PER_PAGE = 10;
private String keyword;
private int pageNumber;
private List<YaItem> yaItems = new ArrayList<YaItem>();
/**
* Constructor
* @param keyword keyword for searching
* @param pageNumber number of page
*/
public YaPage(final String keyword, final int pageNumber) {
this.keyword = keyword;
this.pageNumber = pageNumber;
}
public List<YaItem> getYaItems() {
return yaItems;
}
/**
* Add one SERP item to collection (page)
* @param item one SERP item
*/
public void addYaItem(final YaItem item) {
final int position = (pageNumber * ITEMS_PER_PAGE) + yaItems.size() + 1;
item.setPosition(position);
yaItems.add(item);
}
}
public static class YaItem {
private int position;
@Getter
private String url;
private String domain;
@Getter
private String title;
@Getter
private String description = "";
private String passages = "";
/**
* Constructor
* @param url url of current item
*/
public YaItem(final String url) {
this.url = url;
}
/* Тут набор getter-ов для приватных полей класса... */
public void setPosition(final int position) {
this.position = position;
}
public void setDomain(final String domain) {
this.domain = domain;
}
public void setTitle(final String title) {
this.title = title;
}
public void setDescription(final String description) {
this.description = description;
}
public void addPassage(final String passage) {
passages += passage;
}
@Override
public String toString() {
return "YaItem{" +
"position=" + position +
", url='" + url + '\'' +
", domain='" + domain + '\'' +
", title='" + title + '\'' +
", description='" + description + '\'' +
", passages='" + passages + '\'' +
'}';
}
}
public static class YaHandler extends DefaultHandler {
private static final String IGNORE_TAG = "hlword";
private final CharArrayWriter buffer = new CharArrayWriter();
private YaItem currentItem;
private YaPage yaPage;
/**
* Constructor
* @param yaPage yandex page that will be filled with SERP items
*/
public YaHandler(final YaPage yaPage) {
this.yaPage = yaPage;
}
@Override
public void startElement(
final String uri,
final String localName,
final String qName,
final Attributes attr
) throws SAXException {
super.startElement(uri, localName, qName, attr);
if (!IGNORE_TAG.equals(qName)) {
buffer.reset();
}
}
@Override
public void endElement(
final String uri,
final String localName,
final String qName
) throws SAXException {
super.endElement(uri, localName, qName);
if ("error".equals(qName)) {
throw new IllegalArgumentException("Bad request: " + buffer.toString());
} else if ("url".equals(qName)) {
currentItem = new YaItem(buffer.toString());
} else if ("domain".equals(qName) && currentItem != null) {
currentItem.setDomain(buffer.toString());
} else if ("title".equals(qName) && currentItem != null) {
currentItem.setTitle(clearFromTags(buffer.toString()));
} else if ("headline".equals(qName) && currentItem != null) {
currentItem.setDescription(clearFromTags(buffer.toString()));
} else if ("passage".equals(qName) && currentItem != null) {
currentItem.addPassage(clearFromTags(buffer.toString()));
} else if ("group".equals(qName) && currentItem != null) {
yaPage.addYaItem(currentItem);
}
}
@Override
public void characters(final char[] chars, final int start, final int length)
throws SAXException {
super.characters(chars, start, length);
buffer.write(chars, start, length);
}
/**
* Clear text from unwanted tags
* @param text text to clear
* @return cleared text
*/
private String clearFromTags(final String text) {
return text.replaceAll("<" + IGNORE_TAG +">", "")
.replaceAll("</" + IGNORE_TAG + ">", "");
}
}
@Getter
@Setter
private String user;
@Getter
@Setter
private String key;
@Getter
@Setter
private String url;
/**
* Retrieve Yandex.XML response stream via GET request
* @param query search query
* @param pageNumber number of search page
* @return Yandex.XML response stream
* @throws IOException input/output exception
*/
public InputStream retrieveResponseViaGetRequest(
final String query,
final int pageNumber
) throws IOException {
final StringBuilder address = new StringBuilder(this.url);
address.append("user=").append(user).append(AND)
.append("key=").append(key).append(AND)
.append("query=").append(URLEncoder.encode(query, ENC)).append(AND)
.append("page=").append(pageNumber);
final URL url = new URL(address.toString());
return url.openStream();
}
/**
* Load parsed yandex page from Yandex.XML service
* @param query query for searching
* @param pageNumber number of page
* @return parsed result of searching
* @throws IOException input/output exception
* @throws SAXException parsing exception
*/
public YaPage loadYaPage(final String query, final int pageNumber)
throws IOException, SAXException {
final YaPage result = new YaPage(query, pageNumber);
final XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.setContentHandler(new YaHandler(result));
xmlReader.parse(
new InputSource(
this.retrieveResponseViaGetRequest(query, pageNumber)
)
);
return result;
}
}

View File

@ -1,8 +1,10 @@
name=jircbot jircbot.version=@bot.version@
bot.version=@bot.version@
jircbot.config=config.json
jircbot.url.main=http://localhost:8002
config=config.json
spring.profiles.active=production spring.profiles.active=production