From cc2eb1d13205f4f406f2ec4b05c0bb50c180c0c7 Mon Sep 17 00:00:00 2001 From: Rubenlagu Date: Mon, 3 Aug 2015 19:50:59 +0200 Subject: [PATCH] 1. New weatherbot version --- .idea/inspectionProfiles/Project_Default.xml | 10 + .idea/workspace.xml | 1072 ++++++++------ src/main/java/org/telegram/Commands.java | 4 - ...orceReply.java => ForceReplyKeyboard.java} | 6 +- .../telegram/database/CreationStrings.java | 10 +- .../telegram/database/DatabaseManager.java | 192 ++- .../java/org/telegram/services/BotLogger.java | 4 +- .../telegram/services/CustomTimerTask.java | 69 + .../java/org/telegram/services/Emoji.java | 20 +- .../services/LocalisationService.java | 23 +- .../org/telegram/services/TimerExecutor.java | 108 ++ .../org/telegram/services/WeatherService.java | 122 +- .../org/telegram/structure/WeatherAlert.java | 40 + .../updateshandlers/DirectionsHandlers.java | 17 +- .../updateshandlers/FilesHandlers.java | 4 +- .../updateshandlers/WeatherHandlers.java | 1243 ++++++++++++++--- .../resources/localisation/strings.properties | 78 +- .../localisation/strings_es.properties | 68 +- .../localisation/strings_nl.properties | 75 + .../localisation/strings_pt.properties | 66 +- 20 files changed, 2501 insertions(+), 730 deletions(-) rename src/main/java/org/telegram/api/{ForceReply.java => ForceReplyKeyboard.java} (93%) create mode 100644 src/main/java/org/telegram/services/CustomTimerTask.java create mode 100644 src/main/java/org/telegram/services/TimerExecutor.java create mode 100644 src/main/java/org/telegram/structure/WeatherAlert.java create mode 100644 src/main/resources/localisation/strings_nl.properties diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 2b44d22..38c7409 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -2,6 +2,8 @@ \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 15590bf..c3a5faa 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,21 +2,30 @@ - + + + + - - + + + + + + + + - - - + + + @@ -35,117 +44,147 @@ + + - - + + - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - + + - - + + - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + - - - - - - + + - - - - - - - + + + + - - - - - - + + @@ -157,8 +196,8 @@ @@ -186,57 +225,57 @@ @@ -330,16 +369,106 @@ + + Abstraction issuesJava + + + Assignment issuesJava + + + Class metricsJava + + + Class structureJava + + + Cloning issuesJava + + + Code style issuesJava + + + CodeSpring CoreSpring + + + Concurrency annotation issuesJava + + + Declaration redundancyJava + + + Encapsulation issuesJava + + + GeneralJavaScript + + + ImportsJava + + + Inheritance issuesJava + + + Initialization issuesJava + + + JBoss Seam issues + + + JUnit issuesJava + Java + + Java EE issues + + + JavaScript + + + Logging issuesJava + + + Memory issuesJava + + + Naming conventionsJava + + + Numeric issuesJava + + + Performance issuesJava + Probable bugsJava + + Security issuesJava + + + Serialization issuesJava + + + Spring + + + Spring CoreSpring + + + Threading issuesJava + + + UI Form Problems + + + Visibility issuesJava + - MalformedFormatString + FieldMayBeStatic @@ -368,6 +497,7 @@ + @@ -457,36 +587,6 @@ - @@ -594,7 +693,7 @@ - + @@ -1011,7 +1110,20 @@ - + + + + + + + + + + + + + + 1434854005227 @@ -1205,11 +1317,35 @@ - - @@ -1231,56 +1367,59 @@ + - + - - - + + - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1295,10 +1434,6 @@ - - - - @@ -1320,14 +1455,18 @@ - file://$PROJECT_DIR$/src/main/java/org/telegram/services/WeatherService.java - 135 + 172 @@ -1345,69 +1484,45 @@ file://$PROJECT_DIR$/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java - 66 + 65 file://$PROJECT_DIR$/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java - 60 + 59 file://$PROJECT_DIR$/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java - 57 + 56 - file://$PROJECT_DIR$/src/main/java/org/telegram/services/WeatherService.java - 301 - - - - file://$PROJECT_DIR$/src/main/java/org/telegram/SenderHelper.java - 170 - - - - file://$PROJECT_DIR$/src/main/java/org/telegram/SenderHelper.java - 167 + file://$PROJECT_DIR$/src/main/java/org/telegram/database/DatabaseManager.java + 119 - file://$PROJECT_DIR$/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java - 94 + 376 - file://$PROJECT_DIR$/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java - 237 + 106 - - - file://$PROJECT_DIR$/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java - 254 - - - - file://$PROJECT_DIR$/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java - 59 - - - @@ -1422,447 +1537,536 @@ - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + - + - - + + + - - - - + - - + + - + - - + + - + - - + + - + - - + + - - - - + + + + - - - - - + + + - + - - + + - + - - + + - - - - + + + + - - - - - + + + - + - - - + + - + - - - - - - + + - + - - - - - - - - - - - - + + - + - + - + - - + + - + - - - + + - + - - - - - + + - + - - + + - + - - + - + - - + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + - - - - - - + + + - - + + - - - - + - - - - - - + + + - + - - - + + - - - - - + + - - - - + - + + + + + + + + + - + - + - - + + - - + + + + + + + - + - + - + + + + + + + + + - - - - + + - + - - + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - + - + + + + - - + + - + + + + - - + + - + + + + - - - - - + + + diff --git a/src/main/java/org/telegram/Commands.java b/src/main/java/org/telegram/Commands.java index 1167e2d..8c71e7f 100644 --- a/src/main/java/org/telegram/Commands.java +++ b/src/main/java/org/telegram/Commands.java @@ -8,10 +8,6 @@ package org.telegram; */ public class Commands { public static final String commandInitChar = "/"; - /// Weather forecast command - public static final String WEATHERCOMMAND = commandInitChar + "weather"; - /// Current wether command - public static final String CURRENTWEATHERCOMMAND = commandInitChar + "current"; /// Transifex iOS command public static final String transifexiOSCommand = commandInitChar + "langios"; /// Transifex android command diff --git a/src/main/java/org/telegram/api/ForceReply.java b/src/main/java/org/telegram/api/ForceReplyKeyboard.java similarity index 93% rename from src/main/java/org/telegram/api/ForceReply.java rename to src/main/java/org/telegram/api/ForceReplyKeyboard.java index 3143bfc..6c7ec94 100644 --- a/src/main/java/org/telegram/api/ForceReply.java +++ b/src/main/java/org/telegram/api/ForceReplyKeyboard.java @@ -12,7 +12,7 @@ import org.json.JSONObject; * interfaces without having to sacrifice privacy mode. * @date 22 of June of 2015 */ -public class ForceReply implements ReplyKeyboard { +public class ForceReplyKeyboard implements ReplyKeyboard { public static final String FORCEREPLY_FIELD = "force_reply"; /** @@ -30,12 +30,12 @@ public class ForceReply implements ReplyKeyboard { @JsonProperty(SELECTIVE_FIELD) private Boolean selective; - public ForceReply() { + public ForceReplyKeyboard() { super(); this.forceReply = true; } - public ForceReply(JSONObject jsonObject) { + public ForceReplyKeyboard(JSONObject jsonObject) { super(); this.forceReply = jsonObject.optBoolean(FORCEREPLY_FIELD, true); this.selective = jsonObject.optBoolean(SELECTIVE_FIELD, false); diff --git a/src/main/java/org/telegram/database/CreationStrings.java b/src/main/java/org/telegram/database/CreationStrings.java index f6be70a..59a2fb5 100644 --- a/src/main/java/org/telegram/database/CreationStrings.java +++ b/src/main/java/org/telegram/database/CreationStrings.java @@ -7,7 +7,7 @@ package org.telegram.database; * @date 15 of May of 2015 */ public class CreationStrings { - public static final int version = 3; + public static final int version = 6; public static final String createVersionTable = "CREATE TABLE IF NOT EXISTS Versions(ID INTEGER PRIMARY KEY AUTO_INCREMENT, Version INTEGER);"; public static final String insertCurrentVersion = "INSERT IGNORE INTO Versions (Version) VALUES(%d);"; public static final String createFilesTable = "CREATE TABLE IF NOT EXISTS Files (fileId VARCHAR(100) PRIMARY KEY, userId INTEGER NOT NULL, caption TEXT NOT NULL)"; @@ -19,4 +19,12 @@ public class CreationStrings { "messageId INTEGER NOT NULL DEFAULT 0, origin VARCHAR(100));"; public static final String createLastUpdateDatabase = "CREATE TABLE IF NOT EXISTS LastUpdate (token VARCHAR(125) PRIMARY KEY, updateId INTEGER NOT NULL DEFAULT -1);"; public static final String createUserLanguageDatabase = "CREATE TABLE IF NOT EXISTS UserLanguage (userId INTEGER PRIMARY KEY, languageCode VARCHAR(10) NOT NULL)"; + public static final String createUserWeatherOptionDatabase = "CREATE TABLE IF NOT EXISTS UserWeatherOptions (userId INTEGER PRIMARY KEY, languageCode VARCHAR(10) NOT NULL DEFAULT 'en', " + + "units VARCHAR(10) NOT NULL DEFAULT 'metric')"; + public static final String createWeatherStateTable = "CREATE TABLE IF NOT EXISTS WeatherState (userId INTEGER NOT NULL, chatId INTEGER NOT NULL, state INTEGER NOT NULL DEFAULT 0, " + + "languageCode VARCHAR(10) NOT NULL DEFAULT 'en', " + + "CONSTRAINT `watherPrimaryKey` PRIMARY KEY(userId,chatId));"; + public static final String createWeatherAlertTable = "CREATE TABLE IF NOT EXISTS WeatherAlert (id INTEGER PRIMARY KEY AUTO_INCREMENT, userId INTEGER NOT NULL, cityId INTEGER NOT NULL, " + + "cityName VARCHAR(60) NOT NULL, time INTEGER NOT NULL DEFAULT -1, CONSTRAINT unique_cityNameAlert UNIQUE (userId, cityName)," + + "CONSTRAINT unique_cityIdAlert UNIQUE (userId, cityId));"; } diff --git a/src/main/java/org/telegram/database/DatabaseManager.java b/src/main/java/org/telegram/database/DatabaseManager.java index 1c1a4f8..fd5b168 100644 --- a/src/main/java/org/telegram/database/DatabaseManager.java +++ b/src/main/java/org/telegram/database/DatabaseManager.java @@ -8,12 +8,16 @@ package org.telegram.database; import org.telegram.services.BotLogger; +import org.telegram.structure.WeatherAlert; +import org.telegram.updateshandlers.WeatherHandlers; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; /** * @author Ruben Bermudez @@ -79,6 +83,9 @@ public class DatabaseManager { if (currentVersion == 4) { currentVersion = updateToVersion5(); } + if (currentVersion == 5) { + currentVersion = updateToVersion6(); + } connetion.commitTransaction(); } catch (SQLException e) { log.error(e); @@ -109,6 +116,14 @@ public class DatabaseManager { return 5; } + private int updateToVersion6() throws SQLException { + connetion.executeQuery(CreationStrings.createWeatherStateTable); + connetion.executeQuery(CreationStrings.createUserWeatherOptionDatabase); + connetion.executeQuery(CreationStrings.createWeatherAlertTable); + connetion.executeQuery(String.format(CreationStrings.insertCurrentVersion, 6)); + return 6; + } + private int createNewTables() throws SQLException { connetion.executeQuery(CreationStrings.createVersionTable); connetion.executeQuery(CreationStrings.createFilesTable); @@ -117,6 +132,9 @@ public class DatabaseManager { connetion.executeQuery(CreationStrings.createRecentWeatherTable); connetion.executeQuery(CreationStrings.createDirectionsDatabase); connetion.executeQuery(CreationStrings.createUserLanguageDatabase); + connetion.executeQuery(CreationStrings.createWeatherStateTable); + connetion.executeQuery(CreationStrings.createUserWeatherOptionDatabase); + connetion.executeQuery(CreationStrings.createWeatherAlertTable); return CreationStrings.version; } @@ -233,14 +251,14 @@ public class DatabaseManager { return updatedRows > 0; } - public HashMap getRecentWeather(Integer userId) { - HashMap recentWeather = new HashMap<>(); + public List getRecentWeather(Integer userId) { + List recentWeather = new ArrayList<>(); try { - final PreparedStatement preparedStatement = connetion.getPreparedStatement("select * FROM RecentWeather WHERE userId=?"); + final PreparedStatement preparedStatement = connetion.getPreparedStatement("select * FROM RecentWeather WHERE userId=? order by date desc"); preparedStatement.setInt(1, userId); final ResultSet result = preparedStatement.executeQuery(); while (result.next()) { - recentWeather.put(result.getInt("cityId"), result.getString("cityName")); + recentWeather.add(result.getString("cityName")); } } catch (SQLException e) { e.printStackTrace(); @@ -392,4 +410,170 @@ public class DatabaseManager { } return updatedRows > 0; } + + public int getWeatherState(Integer userId, Integer chatId) { + int state = 0; + try { + final PreparedStatement preparedStatement = connetion.getPreparedStatement("SELECT state FROM WeatherState WHERE userId = ? AND chatId = ?"); + preparedStatement.setInt(1, userId); + preparedStatement.setInt(2, chatId); + final ResultSet result = preparedStatement.executeQuery(); + if (result.next()) { + state = result.getInt("state"); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return state; + } + + public boolean insertWeatherState(Integer userId, Integer chatId, int state) { + int updatedRows = 0; + try { + final PreparedStatement preparedStatement = connetion.getPreparedStatement("REPLACE INTO WeatherState (userId, chatId, state) VALUES (?, ?, ?)"); + preparedStatement.setInt(1, userId); + preparedStatement.setInt(2, chatId); + preparedStatement.setInt(3, state); + updatedRows = preparedStatement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + return updatedRows > 0; + } + + public Integer getRecentWeatherIdByCity(Integer userId, String city) { + Integer cityId = null; + try { + final PreparedStatement preparedStatement = connetion.getPreparedStatement("select cityId FROM RecentWeather WHERE userId=? AND cityName=?"); + preparedStatement.setInt(1, userId); + preparedStatement.setString(2, city); + final ResultSet result = preparedStatement.executeQuery(); + if (result.next()) { + cityId = result.getInt("cityId"); + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return cityId; + } + + public String[] getUserWeatherOptions(Integer userId) { + String[] options = new String[] {"en", "metric"}; + try { + final PreparedStatement preparedStatement = connetion.getPreparedStatement("SELECT * FROM UserWeatherOptions WHERE userId = ?"); + preparedStatement.setInt(1, userId); + final ResultSet result = preparedStatement.executeQuery(); + if (result.next()) { + options[0] = result.getString("languageCode"); + options[1] = result.getString("units"); + } else { + addNewUserWeatherOptions(userId); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return options; + } + + private boolean addNewUserWeatherOptions(Integer userId) { + int updatedRows = 0; + try { + final PreparedStatement preparedStatement = connetion.getPreparedStatement("INSERT INTO UserWeatherOptions (userId) VALUES (?)"); + preparedStatement.setInt(1, userId); + updatedRows = preparedStatement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + return updatedRows > 0; + } + + public boolean putUserWeatherLanguageOption(Integer userId, String language) { + int updatedRows = 0; + try { + final PreparedStatement preparedStatement = connetion.getPreparedStatement("UPDATE UserWeatherOptions SET languageCode = ? WHERE userId = ?"); + preparedStatement.setString(1, language); + preparedStatement.setInt(2, userId); + updatedRows = preparedStatement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + return updatedRows > 0; + } + + public boolean putUserWeatherUnitsOption(Integer userId, String units) { + int updatedRows = 0; + try { + final PreparedStatement preparedStatement = connetion.getPreparedStatement("UPDATE UserWeatherOptions SET units = ? WHERE userId = ?"); + preparedStatement.setString(1, units); + preparedStatement.setInt(2, userId); + updatedRows = preparedStatement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + return updatedRows > 0; + } + + public boolean createNewWeatherAlert(int userId, Integer cityId, String cityName) { + int updatedRows = 0; + try { + final PreparedStatement preparedStatement = connetion.getPreparedStatement("INSERT INTO WeatherAlert (userId, cityId, cityName) VALUES (?,?,?)"); + preparedStatement.setInt(1, userId); + preparedStatement.setInt(2, cityId); + preparedStatement.setString(3, cityName); + updatedRows = preparedStatement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + return updatedRows > 0; + } + + public List getAlertCitiesNameByUser(int userId) { + List alertCitiesNames = new ArrayList<>(); + try { + final PreparedStatement preparedStatement = connetion.getPreparedStatement("select cityName FROM WeatherAlert WHERE userId=?"); + preparedStatement.setInt(1, userId); + final ResultSet result = preparedStatement.executeQuery(); + while (result.next()) { + alertCitiesNames.add(result.getString("cityName")); + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return alertCitiesNames; + } + + public boolean deleteAlertCity(Integer userId, String cityName) { + int updatedRows = 0; + try { + final PreparedStatement preparedStatement = connetion.getPreparedStatement("DELETE FROM WeatherAlert WHERE userId=? AND cityName=?;"); + preparedStatement.setInt(1, userId); + preparedStatement.setString(2, cityName); + updatedRows = preparedStatement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + return updatedRows > 0; + } + + public List getAllAlerts() { + List allAlerts = new ArrayList<>(); + + try { + final PreparedStatement preparedStatement = connetion.getPreparedStatement("select * FROM WeatherAlert"); + final ResultSet result = preparedStatement.executeQuery(); + while (result.next()) { + WeatherAlert weatherAlert = new WeatherAlert(); + weatherAlert.setId(result.getInt("id")); + weatherAlert.setUserId(result.getInt("userId")); + weatherAlert.setCityId(result.getInt("cityId")); + allAlerts.add(weatherAlert); + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return allAlerts; + } } diff --git a/src/main/java/org/telegram/services/BotLogger.java b/src/main/java/org/telegram/services/BotLogger.java index 752fffd..9568050 100644 --- a/src/main/java/org/telegram/services/BotLogger.java +++ b/src/main/java/org/telegram/services/BotLogger.java @@ -52,9 +52,9 @@ public class BotLogger { private BotLogger(String classname) { logger = Logger.getLogger(classname); - logger.setLevel(Level.WARNING); + logger.setLevel(Level.ALL); ConsoleHandler handler = new ConsoleHandler(); - handler.setLevel(Level.WARNING); + handler.setLevel(Level.ALL); logger.addHandler(handler); lastFileDate = new GregorianCalendar(); if (currentFileName == null || currentFileName.length() == 0) { diff --git a/src/main/java/org/telegram/services/CustomTimerTask.java b/src/main/java/org/telegram/services/CustomTimerTask.java new file mode 100644 index 0000000..f387092 --- /dev/null +++ b/src/main/java/org/telegram/services/CustomTimerTask.java @@ -0,0 +1,69 @@ +package org.telegram.services; + +/** + * @author Ruben Bermudez + * @version 2.0 + * @brief Task to be execute periodically + * @date 28/01/15 + */ +public abstract class CustomTimerTask { + private String taskName = ""; ///< Task name + private int times = 1; + + /** + * Constructor + * + * @param taskName Name of the task + */ + public CustomTimerTask(String taskName, int times) { + this.taskName = taskName; + this.times = times; + } + + /** + * Get name + * + * @return name + */ + public String getTaskName() { + return this.taskName; + } + + /** + * Set name + * + * @param taskName new name + */ + public void setTaskName(String taskName) { + this.taskName = taskName; + } + + /** + * Getter for the times + * + * @return Remainint times the task must be executed + */ + public int getTimes() { + return this.times; + } + + /** + * Setter for the times + * + * @param times Number of times the task must be executed + */ + public void setTimes(int times) { + this.times = times; + } + + public void reduceTimes() { + if (this.times > 0) { + this.times -= 1; + } + } + + /** + * @abstract Should contain the functionality of the task + */ + public abstract void execute(); +} diff --git a/src/main/java/org/telegram/services/Emoji.java b/src/main/java/org/telegram/services/Emoji.java index 0123323..cbe2c32 100644 --- a/src/main/java/org/telegram/services/Emoji.java +++ b/src/main/java/org/telegram/services/Emoji.java @@ -144,7 +144,25 @@ public enum Emoji { CLOUD(null, '\u2601'), // Others - LEFT_RIGHT_ARROW(null, '\u2194'); + LEFT_RIGHT_ARROW(null, '\u2194'), + ALARM_CLOCK(null, '\u23F0'), + SOON_WITH_RIGHTWARDS_ARROW_ABOVE('\uD83D', '\uDD1C'), + EARTH_GLOBE_EUROPE_AFRICA('\uD83C', '\uDF0D'), + GLOBE_WITH_MERIDIANS('\uD83C', '\uDF10'), + STRAIGHT_RULER('\uD83D', '\uDCCF'), + INFORMATION_SOURCE(null, '\u2139'), + BLACK_RIGHT_POINTING_DOUBLE_TRIANGLE(null, '\u23E9'), + BLACK_RIGHT_POINTING_TRIANGLE(null, '\u25B6'), + BACK_WITH_LEFTWARDS_ARROW_ABOVE('\uD83D', '\uDD19'), + WRENCH('\uD83D', '\uDD27'), + DIGIT_THREE(null, '\u0033'), + CLIPBOARD('\uD83D', '\uDCCB'), + THUMBS_UP_SIGN('\uD83D', '\uDC4D'), + WHITE_RIGHT_POINTING_BACKHAND_INDEX('\uD83D', '\uDC49'), + TEAR_OFF_CALENDAR('\uD83D', '\uDCC6'), + LARGE_ORANGE_DIAMOND('\uD83D', '\uDD36'), + HUNDRED_POINTS_SYMBOL('\uD83D', '\uDCAF'), + ROUND_PUSHPIN('\uD83D', '\uDCCD'); Character firstChar; Character secondChar; diff --git a/src/main/java/org/telegram/services/LocalisationService.java b/src/main/java/org/telegram/services/LocalisationService.java index 6b51c33..afc2cf3 100644 --- a/src/main/java/org/telegram/services/LocalisationService.java +++ b/src/main/java/org/telegram/services/LocalisationService.java @@ -3,10 +3,7 @@ package org.telegram.services; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.ResourceBundle; +import java.util.*; /** * @author Ruben Bermudez @@ -16,7 +13,7 @@ import java.util.ResourceBundle; */ public class LocalisationService { private static LocalisationService instance = null; - public HashMap supportedLanguages = new HashMap<>(); + private final HashMap supportedLanguages = new HashMap<>(); private ResourceBundle english; private ResourceBundle spanish; @@ -91,11 +88,11 @@ public class LocalisationService { supportedLanguages.put("es", "Español"); portuguese = ResourceBundle.getBundle("localisation.strings", new Locale("pt", "PT"), loader); supportedLanguages.put("pt", "Português"); + dutch = ResourceBundle.getBundle("localisation.strings", new Locale("nl", "NL"), loader); + supportedLanguages.put("nl", "Nederlands"); /* german = ResourceBundle.getBundle("localisation.strings", new Locale("de", "DE"), loader); supportedLanguages.put("de", "Deutsch"); - dutch = ResourceBundle.getBundle("localisation.strings", new Locale("nl", "NL"), loader); - supportedLanguages.put("nl", "Dutch"); italian = ResourceBundle.getBundle("localisation.strings", new Locale("it", "IT"), loader); supportedLanguages.put("it", "Italian"); french = ResourceBundle.getBundle("localisation.strings", new Locale("fr", "FR"), loader); @@ -150,10 +147,10 @@ public class LocalisationService { case "pt": result = portuguese.getString(key); break; - /*case "nl": + case "nl": result = dutch.getString(key); break; - case "de": + /*case "de": result = german.getString(key); break; case "it": @@ -199,4 +196,12 @@ public class LocalisationService { return result; } + + public HashMap getSupportedLanguages() { + return supportedLanguages; + } + + public String getLanguageCodeByName(String language) { + return supportedLanguages.entrySet().stream().filter(x -> x.getValue().equals(language)).findFirst().get().getKey(); + } } diff --git a/src/main/java/org/telegram/services/TimerExecutor.java b/src/main/java/org/telegram/services/TimerExecutor.java new file mode 100644 index 0000000..1f87ce4 --- /dev/null +++ b/src/main/java/org/telegram/services/TimerExecutor.java @@ -0,0 +1,108 @@ +package org.telegram.services; + +import java.time.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * @author Ruben Bermudez + * @version 2.0 + * @brief Exectue a task periodically + * @date 27/01/25 + */ +public class TimerExecutor { + private static volatile BotLogger log = BotLogger.getLogger(TimerExecutor.class.getName()); + private static volatile TimerExecutor instance; ///< Instance + private static final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); ///< Thread to execute operations + + /** + * Private constructor due to singleton + */ + private TimerExecutor() { + } + + /** + * Singleton pattern + * + * @return Instance of the executor + */ + public static TimerExecutor getInstance() { + final TimerExecutor currentInstance; + if (instance == null) { + synchronized (TimerExecutor.class) { + if (instance == null) { + instance = new TimerExecutor(); + } + currentInstance = instance; + } + } else { + currentInstance = instance; + } + + return currentInstance; + } + + /** + * Add a new CustomTimerTask to be executed + * + * @param task Task to execute + * @param targetHour Hour to execute it + * @param targetMin Minute to execute it + * @param targetSec Second to execute it + */ + public void startExecutionEveryDayAt(CustomTimerTask task, int targetHour, int targetMin, int targetSec) { + log.warn("Posting new task" + task.getTaskName()); + final Runnable taskWrapper = () -> { + try { + task.execute(); + task.reduceTimes(); + startExecutionEveryDayAt(task, targetHour, targetMin, targetSec); + } catch (Exception e) { + log.severe("Bot threw an unexpected exception at TimerExecutor", e); + } + }; + if (task.getTimes() != 0) { + final long delay = computNextDilay(targetHour, targetMin, targetSec); + executorService.schedule(taskWrapper, delay, TimeUnit.SECONDS); + } + } + + /** + * Find out next daily execution + * + * @param targetHour Target hour + * @param targetMin Target minute + * @param targetSec Target second + * @return time in second to wait + */ + private long computNextDilay(int targetHour, int targetMin, int targetSec) { + final LocalDateTime localNow = LocalDateTime.now(Clock.systemUTC()); + LocalDateTime localNextTarget = localNow.withHour(targetHour).withMinute(targetMin).withSecond(targetSec); + while (localNow.compareTo(localNextTarget) > 0) { + localNextTarget = localNextTarget.plusDays(1); + } + + final Duration duration = Duration.between(localNow, localNextTarget); + return duration.getSeconds(); + } + + @Override + public void finalize() { + this.stop(); + } + + /** + * Stop the thread + */ + public void stop() { + executorService.shutdown(); + try { + executorService.awaitTermination(1, TimeUnit.DAYS); + } catch (InterruptedException ex) { + log.severe(ex); + } catch (Exception e) { + log.severe("Bot threw an unexpected exception at TimerExecutor", e); + } + } +} diff --git a/src/main/java/org/telegram/services/WeatherService.java b/src/main/java/org/telegram/services/WeatherService.java index 8ecf17b..fad48d6 100644 --- a/src/main/java/org/telegram/services/WeatherService.java +++ b/src/main/java/org/telegram/services/WeatherService.java @@ -28,21 +28,16 @@ import java.time.format.DateTimeFormatter; public class WeatherService { private static volatile BotLogger log = BotLogger.getLogger(WeatherService.class.getName()); - private static final String FILEIDSUNNY = "BQADBAADEgoAAnVbtwRqrxn89vjb1wI"; - private static final String FILEIDFEWCLOUDS = "BQADBAADEwoAAnVbtwT3NZvlhOXiKQI"; - private static final String FILEIDCLOUDS = "BQADBAADFAoAAnVbtwR8DOcw8SdYbwI"; - private static final String FILEIDSHOWERRAIN = "BQADBAADFQoAAnVbtwQL2CuuhfiIYgI"; - private static final String FILEIDRAIN = "BQADBAADFgoAAnVbtwSxZkQoAlHhJAI"; - private static final String FILEIDTHUNDERSTORM = "BQADBAADGAoAAnVbtwQp1kcPThwm7QI"; - private static final String FILEIDSNOW = "BQADBAADGAoAAnVbtwRtYBVrEJPQPQI"; - private static final String FILEIDFOGGY = "BQADBAADFwoAAnVbtwRwJotTvbcb0gI"; + public static final String METRICSYSTEM = "metric"; + public static final String IMPERIALSYSTEM = "imperial"; private static final String BASEURL = "http://api.openweathermap.org/data/2.5/"; ///< Base url for REST private static final String FORECASTPATH = "forecast/daily"; private static final String CURRENTPATH = "weather"; private static final String APIIDEND = "&APPID=" + BuildVars.OPENWEATHERAPIKEY; - private static final String FORECASTPARAMS = "&cnt=3&units=metric&lang=@language@"; - private static final String CURRENTPARAMS = "&cnt=1&units=metric&lang=@language@"; + private static final String FORECASTPARAMS = "&cnt=3&units=@units@&lang=@language@"; + private static final String ALERTPARAMS = "&cnt=1&units=@units@&lang=@language@"; + private static final String CURRENTPARAMS = "&cnt=1&units=@units@&lang=@language@"; private static final DateTimeFormatter dateFormaterFromDate = DateTimeFormatter.ofPattern("dd/MM/yyyy"); ///< Date to text formater private static volatile WeatherService instance; ///< Instance of this class @@ -72,6 +67,47 @@ public class WeatherService { return currentInstance; } + /** + * Fetch the weather of a city for one day + * + * @param cityId City to get the weather + * @return userHash to be send to use + * @note Forecast for the day + */ + public String fetchWeatherAlert(int cityId, int userId, String language, String units) { + String cityFound; + String responseToUser; + try { + String completURL = BASEURL + FORECASTPATH + "?" + getCityQuery(cityId + "") + + ALERTPARAMS.replace("@language@", language).replace("@units@", units) + APIIDEND; + CloseableHttpClient client = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); + HttpGet request = new HttpGet(completURL); + + CloseableHttpResponse response = client.execute(request); + HttpEntity ht = response.getEntity(); + + BufferedHttpEntity buf = new BufferedHttpEntity(ht); + String responseString = EntityUtils.toString(buf, "UTF-8"); + + JSONObject jsonObject = new JSONObject(responseString); + log.warning(jsonObject.toString()); + if (jsonObject.getInt("cod") == 200) { + cityFound = jsonObject.getJSONObject("city").getString("name") + " (" + + jsonObject.getJSONObject("city").getString("country") + ")"; + saveRecentWeather(userId, cityFound, jsonObject.getJSONObject("city").getInt("id")); + responseToUser = String.format(LocalisationService.getInstance().getString("weatherAlert", language), + cityFound, convertListOfForecastToString(jsonObject, language, units, false)); + } else { + log.warning(jsonObject.toString()); + responseToUser = LocalisationService.getInstance().getString("cityNotFound", language); + } + } catch (Exception e) { + log.error(e); + responseToUser = LocalisationService.getInstance().getString("errorFetchingWeather", language); + } + return responseToUser; + } + /** * Fetch the weather of a city * @@ -79,12 +115,12 @@ public class WeatherService { * @return userHash to be send to use * @note Forecast for the following 3 days */ - public String fetchWeatherForecast(String city, Integer userId, String language) { + public String fetchWeatherForecast(String city, Integer userId, String language, String units) { String cityFound; String responseToUser; try { String completURL = BASEURL + FORECASTPATH + "?" + getCityQuery(city) + - FORECASTPARAMS.replace("@language@", language) + APIIDEND; + FORECASTPARAMS.replace("@language@", language).replace("@units@", units) + APIIDEND; CloseableHttpClient client = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); HttpGet request = new HttpGet(completURL); @@ -101,7 +137,7 @@ public class WeatherService { jsonObject.getJSONObject("city").getString("country") + ")"; saveRecentWeather(userId, cityFound, jsonObject.getJSONObject("city").getInt("id")); responseToUser = String.format(LocalisationService.getInstance().getString("weatherForcast", language), - cityFound, convertListOfForecastToString(jsonObject, language)); + cityFound, convertListOfForecastToString(jsonObject, language, units, true)); } else { log.warning(jsonObject.toString()); responseToUser = LocalisationService.getInstance().getString("cityNotFound", language); @@ -119,12 +155,13 @@ public class WeatherService { * @return userHash to be send to use * @note Forecast for the following 3 days */ - public String fetchWeatherForecastByLocation(Double longitude, Double latitude, Integer userId, String language) { + public String fetchWeatherForecastByLocation(Double longitude, Double latitude, Integer userId, String language, String units) { String cityFound; String responseToUser; try { String completURL = BASEURL + FORECASTPATH + "?lat=" + URLEncoder.encode(latitude + "", "UTF-8") + "&lon=" - + URLEncoder.encode(longitude + "", "UTF-8") + FORECASTPARAMS.replace("@language@", language) + APIIDEND;; + + URLEncoder.encode(longitude + "", "UTF-8") + + FORECASTPARAMS.replace("@language@", language).replace("@units@", units) + APIIDEND;; CloseableHttpClient client = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); HttpGet request = new HttpGet(completURL); CloseableHttpResponse response = client.execute(request); @@ -139,7 +176,7 @@ public class WeatherService { jsonObject.getJSONObject("city").getString("country") + ")"; saveRecentWeather(userId, cityFound, jsonObject.getJSONObject("city").getInt("id")); responseToUser = String.format(LocalisationService.getInstance().getString("weatherForcast", language), - cityFound, convertListOfForecastToString(jsonObject, language)); + cityFound, convertListOfForecastToString(jsonObject, language, units, true)); } else { log.warning(jsonObject.toString()); responseToUser = LocalisationService.getInstance().getString("cityNotFound", language); @@ -158,13 +195,13 @@ public class WeatherService { * @return userHash to be send to use * @note Forecast for the following 3 days */ - public String fetchWeatherCurrent(String city, Integer userId, String language) { + public String fetchWeatherCurrent(String city, Integer userId, String language, String units) { String cityFound; String responseToUser; Emoji emoji = null; try { String completURL = BASEURL + CURRENTPATH + "?" + getCityQuery(city) + - CURRENTPARAMS.replace("@language@", language) + APIIDEND; + CURRENTPARAMS.replace("@language@", language).replace("@units@", units) + APIIDEND; CloseableHttpClient client = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); HttpGet request = new HttpGet(completURL); CloseableHttpResponse response = client.execute(request); @@ -180,7 +217,7 @@ public class WeatherService { saveRecentWeather(userId, cityFound, jsonObject.getInt("id")); emoji = getEmojiForWeather(jsonObject.getJSONArray("weather").getJSONObject(0)); responseToUser = String.format(LocalisationService.getInstance().getString("weatherCurrent", language), - cityFound, convertCurrentWeatherToString(jsonObject, language, emoji)); + cityFound, convertCurrentWeatherToString(jsonObject, language, units, emoji)); } else { log.warning(jsonObject.toString()); responseToUser = LocalisationService.getInstance().getString("cityNotFound", language); @@ -198,12 +235,13 @@ public class WeatherService { * @return userHash to be send to use * @note Forecast for the following 3 days */ - public String fetchWeatherCurrentByLocation(Double longitude, Double latitude, Integer userId, String language) { + public String fetchWeatherCurrentByLocation(Double longitude, Double latitude, Integer userId, String language, String units) { String cityFound; String responseToUser; try { - String completURL = BASEURL + CURRENTPATH + "?q=" + URLEncoder.encode("lat=" + latitude + "&lon=" + - longitude, "UTF-8") + CURRENTPARAMS.replace("@language@", language) + APIIDEND;; + String completURL = BASEURL + CURRENTPATH + "?lat=" + URLEncoder.encode(latitude + "", "UTF-8") + "&lon=" + + URLEncoder.encode(longitude + "", "UTF-8") + + CURRENTPARAMS.replace("@language@", language).replace("@units@", units) + APIIDEND;; CloseableHttpClient client = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); HttpGet request = new HttpGet(completURL); CloseableHttpResponse response = client.execute(request); @@ -218,7 +256,7 @@ public class WeatherService { jsonObject.getJSONObject("sys").getString("country") + ")"; saveRecentWeather(userId, cityFound, jsonObject.getInt("id")); responseToUser = String.format(LocalisationService.getInstance().getString("weatherCurrent", language), - cityFound, convertCurrentWeatherToString(jsonObject, language, null)); + cityFound, convertCurrentWeatherToString(jsonObject, language, units, null)); } else { log.warning(jsonObject.toString()); responseToUser = LocalisationService.getInstance().getString("cityNotFound", language); @@ -230,12 +268,17 @@ public class WeatherService { return responseToUser; } - private String convertCurrentWeatherToString(JSONObject jsonObject, String language, Emoji emoji) { + private String convertCurrentWeatherToString(JSONObject jsonObject, String language, String units, Emoji emoji) { String temp = jsonObject.getJSONObject("main").getDouble("temp")+""; String cloudiness = jsonObject.getJSONObject("clouds").getInt("all") + "%"; String weatherDesc = jsonObject.getJSONArray("weather").getJSONObject(0).getString("description"); - String responseToUser = LocalisationService.getInstance().getString("currentWeatherPart", language); + String responseToUser; + if (units.equals(METRICSYSTEM)) { + responseToUser = LocalisationService.getInstance().getString("currentWeatherPartMetric", language); + } else { + responseToUser = LocalisationService.getInstance().getString("currentWeatherPartImperial", language); + } responseToUser = String.format(responseToUser, emoji == null ? weatherDesc : emoji.toString(), cloudiness, temp); return responseToUser; @@ -247,11 +290,11 @@ public class WeatherService { * @param jsonObject JSONObject contining the list * @return String to be sent to the user */ - private String convertListOfForecastToString(JSONObject jsonObject, String language) { + private String convertListOfForecastToString(JSONObject jsonObject, String language, String units, boolean addDate) { String responseToUser = ""; for (int i = 0; i < jsonObject.getJSONArray("list").length(); i++) { JSONObject internalJSON = jsonObject.getJSONArray("list").getJSONObject(i); - responseToUser += convertInternalInformationToString(internalJSON, language); + responseToUser += convertInternalInformationToString(internalJSON, language, units, addDate); } return responseToUser; } @@ -262,7 +305,7 @@ public class WeatherService { * @param internalJSON JSONObject containing the part to convert * @return String to be sent to the user */ - private String convertInternalInformationToString(JSONObject internalJSON, String language) { + private String convertInternalInformationToString(JSONObject internalJSON, String language, String units, boolean addDate) { String responseToUser = ""; LocalDate date; String tempMax; @@ -275,9 +318,26 @@ public class WeatherService { Emoji emoji = getEmojiForWeather(internalJSON.getJSONArray("weather").getJSONObject(0)); weatherDesc = weatherObject.getString("description"); - responseToUser = LocalisationService.getInstance().getString("forecastWeatherPart", language); - responseToUser = String.format(responseToUser, dateFormaterFromDate.format(date), - emoji == null ? weatherDesc : emoji.toString(), tempMax, tempMin); + if (units.equals(METRICSYSTEM)) { + if (addDate) { + responseToUser = LocalisationService.getInstance().getString("forecastWeatherPartMetric", language); + } else { + responseToUser = LocalisationService.getInstance().getString("alertWeatherPartMetric", language); + } + } else { + if (addDate) { + responseToUser = LocalisationService.getInstance().getString("forecastWeatherPartImperial", language); + } else { + responseToUser = LocalisationService.getInstance().getString("alertWeatherPartImperial", language); + } + } + if (addDate) { + responseToUser = String.format(responseToUser, Emoji.LARGE_ORANGE_DIAMOND.toString(), + dateFormaterFromDate.format(date), emoji == null ? weatherDesc : emoji.toString(), tempMax, tempMin); + } else { + responseToUser = String.format(responseToUser, emoji == null ? weatherDesc : emoji.toString(), + tempMax, tempMin); + } return responseToUser; } diff --git a/src/main/java/org/telegram/structure/WeatherAlert.java b/src/main/java/org/telegram/structure/WeatherAlert.java new file mode 100644 index 0000000..bbf8c7b --- /dev/null +++ b/src/main/java/org/telegram/structure/WeatherAlert.java @@ -0,0 +1,40 @@ +package org.telegram.structure; + +/** + * @author Ruben Bermudez + * @version 1.0 + * @brief Weather Alert representation + * @date 23 of July of 2015 + */ +public class WeatherAlert { + private int id; + private int userId; + private int cityId; + + public WeatherAlert() { + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public int getCityId() { + return cityId; + } + + public void setCityId(int cityId) { + this.cityId = cityId; + } +} diff --git a/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java b/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java index 835d588..7efd862 100644 --- a/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java +++ b/src/main/java/org/telegram/updateshandlers/DirectionsHandlers.java @@ -9,7 +9,6 @@ import org.telegram.services.LocalisationService; import org.telegram.updatesreceivers.UpdatesThread; import org.telegram.updatesreceivers.Webhook; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -112,9 +111,9 @@ public class DirectionsHandlers implements UpdatesCallback { SendMessage sendMessageRequest = new SendMessage(); sendMessageRequest.setChatId(message.getChatId()); sendMessageRequest.setReplayToMessageId(message.getMessageId()); - ForceReply forceReply = new ForceReply(); - forceReply.setSelective(true); - sendMessageRequest.setReplayMarkup(forceReply); + ForceReplyKeyboard forceReplyKeyboard = new ForceReplyKeyboard(); + forceReplyKeyboard.setSelective(true); + sendMessageRequest.setReplayMarkup(forceReplyKeyboard); sendMessageRequest.setText(LocalisationService.getInstance().getString("sendDestination", language)); Message sentMessage = SenderHelper.SendMessage(sendMessageRequest, TOKEN); if (sentMessage != null) { @@ -137,9 +136,9 @@ public class DirectionsHandlers implements UpdatesCallback { SendMessage sendMessageRequest = new SendMessage(); sendMessageRequest.setChatId(message.getChatId()); sendMessageRequest.setReplayToMessageId(message.getMessageId()); - ForceReply forceReply = new ForceReply(); - forceReply.setSelective(true); - sendMessageRequest.setReplayMarkup(forceReply); + ForceReplyKeyboard forceReplyKeyboard = new ForceReplyKeyboard(); + forceReplyKeyboard.setSelective(true); + sendMessageRequest.setReplayMarkup(forceReplyKeyboard); sendMessageRequest.setText(LocalisationService.getInstance().getString("initDirections", language)); Message sentMessage = SenderHelper.SendMessage(sendMessageRequest, TOKEN); if (sentMessage != null) { @@ -152,7 +151,7 @@ public class DirectionsHandlers implements UpdatesCallback { SendMessage sendMessageRequest = new SendMessage(); sendMessageRequest.setChatId(message.getChatId()); ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup(); - HashMap languages = LocalisationService.getInstance().supportedLanguages; + HashMap languages = LocalisationService.getInstance().getSupportedLanguages(); List> commands = new ArrayList<>(); for (Map.Entry entry : languages.entrySet()) { List commandRow = new ArrayList<>(); @@ -173,7 +172,7 @@ public class DirectionsHandlers implements UpdatesCallback { String[] parts = message.getText().split("-->", 2); SendMessage sendMessageRequest = new SendMessage(); sendMessageRequest.setChatId(message.getChatId()); - if (LocalisationService.getInstance().supportedLanguages.containsKey(parts[0].trim())) { + if (LocalisationService.getInstance().getSupportedLanguages().containsKey(parts[0].trim())) { DatabaseManager.getInstance().putUserLanguage(message.getFrom().getId(), parts[0].trim()); sendMessageRequest.setText(LocalisationService.getInstance().getString("languageModified", parts[0].trim())); } else { diff --git a/src/main/java/org/telegram/updateshandlers/FilesHandlers.java b/src/main/java/org/telegram/updateshandlers/FilesHandlers.java index 8af672a..e55237b 100644 --- a/src/main/java/org/telegram/updateshandlers/FilesHandlers.java +++ b/src/main/java/org/telegram/updateshandlers/FilesHandlers.java @@ -210,7 +210,7 @@ public class FilesHandlers implements UpdatesCallback { SendMessage sendMessageRequest = new SendMessage(); sendMessageRequest.setChatId(message.getChatId()); ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup(); - HashMap languages = LocalisationService.getInstance().supportedLanguages; + HashMap languages = LocalisationService.getInstance().getSupportedLanguages(); List> commands = new ArrayList<>(); for (Map.Entry entry : languages.entrySet()) { List commandRow = new ArrayList<>(); @@ -231,7 +231,7 @@ public class FilesHandlers implements UpdatesCallback { String[] parts = message.getText().split(Emoji.LEFT_RIGHT_ARROW.toString(), 2); SendMessage sendMessageRequest = new SendMessage(); sendMessageRequest.setChatId(message.getChatId()); - if (LocalisationService.getInstance().supportedLanguages.containsKey(parts[0].trim())) { + if (LocalisationService.getInstance().getSupportedLanguages().containsKey(parts[0].trim())) { DatabaseManager.getInstance().putUserLanguage(message.getFrom().getId(), parts[0].trim()); sendMessageRequest.setText(LocalisationService.getInstance().getString("languageModified", parts[0].trim())); } else { diff --git a/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java b/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java index 8389e9d..3f3f64c 100644 --- a/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java +++ b/src/main/java/org/telegram/updateshandlers/WeatherHandlers.java @@ -2,23 +2,18 @@ package org.telegram.updateshandlers; import org.telegram.BotConfig; import org.telegram.BuildVars; -import org.telegram.Commands; import org.telegram.SenderHelper; import org.telegram.api.*; import org.telegram.database.DatabaseManager; import org.telegram.methods.SendMessage; -import org.telegram.services.BotLogger; -import org.telegram.services.LocalisationService; -import org.telegram.services.WeatherService; +import org.telegram.services.*; +import org.telegram.structure.WeatherAlert; import org.telegram.updatesreceivers.UpdatesThread; import org.telegram.updatesreceivers.Webhook; +import javax.swing.text.JTextComponent; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; /** * @author Ruben Bermudez @@ -27,251 +22,1109 @@ import java.util.concurrent.ConcurrentLinkedQueue; * @date 24 of June of 2015 */ public class WeatherHandlers implements UpdatesCallback { - private static volatile BotLogger log = BotLogger.getLogger(WeatherHandlers.class.getName()); - private static final String TOKEN = BotConfig.TOKENWEATHER; - private static final int CURRENTWEATHERID = 0; - private static final int FORECASTWEATHERID = 1; - + private static final int MAINMENU = 1; + private static final int CURRENTWEATHER = 2; + private static final int CURRENTNEWWEATHER = 3; + private static final int CURRENTLOCATIONWEATHER = 4; + private static final int FORECASTWEATHER = 5; + private static final int FORECASTNEWWEATHER = 6; + private static final int FORECASTLOCATIONWEATHER = 7; + private static final int ALERT = 8; + private static final int ALERTNEW = 9; + private static final int ALERTDELETE = 10; + private static final int SETTINGS = 11; + private static final int LANGUAGE = 12; + private static final int UNITS = 13; private static final String webhookPath = "weatherBot"; - private final Webhook webhook; - private final UpdatesThread updatesThread; - private ConcurrentHashMap listOfSentMessages = new ConcurrentHashMap<>(); - private final ConcurrentLinkedQueue languageMessages = new ConcurrentLinkedQueue<>(); public WeatherHandlers() { + Webhook webhook; if (BuildVars.useWebHook) { webhook = new Webhook(this, webhookPath); - updatesThread = null; SenderHelper.SendWebhook(webhook.getURL(), TOKEN); } else { - webhook = null; SenderHelper.SendWebhook("", TOKEN); - updatesThread = new UpdatesThread(TOKEN, this); + new UpdatesThread(TOKEN, this); + } + startAlertTimers(); + } + + private static void startAlertTimers() { + TimerExecutor.getInstance().startExecutionEveryDayAt(new CustomTimerTask("First day alert", -1) { + @Override + public void execute() { + sendAlerts(); + } + }, 0, 0, 0); + + TimerExecutor.getInstance().startExecutionEveryDayAt(new CustomTimerTask("Second day alert", -1) { + @Override + public void execute() { + sendAlerts(); + } + }, 12, 0, 0); + } + + private static void sendAlerts() { + List allAlerts = DatabaseManager.getInstance().getAllAlerts(); + for (WeatherAlert weatherAlert : allAlerts) { + String[] userOptions = DatabaseManager.getInstance().getUserWeatherOptions(weatherAlert.getUserId()); + String weather = WeatherService.getInstance().fetchWeatherAlert(weatherAlert.getCityId(), + weatherAlert.getUserId(), userOptions[0], userOptions[1]); + SendMessage sendMessage = new SendMessage(); + sendMessage.setChatId(weatherAlert.getUserId()); + sendMessage.setText(weather); + sendBuiltMessage(sendMessage); } } @Override public void onUpdateReceived(Update update) { - sendWeatherInformation(update); + Message message = update.getMessage(); + if (message != null) { + handleIncomingMessage(message); + } } - public void sendWeatherInformation(Update update) { - Message message = update.getMessage(); - if (message != null && message.hasText()) { - if (languageMessages.contains(message.getFrom().getId())) { - onLanguageReceived(message); + private static void onCancelCommand(Integer chatId, Integer userId, Integer messageId, ReplyKeyboard replyKeyboard, String language) { + SendMessage sendMessage = new SendMessage(); + sendMessage.setChatId(chatId); + sendMessage.setReplayMarkup(getMainMenuKeyboard(language)); + sendMessage.setReplayToMessageId(messageId); + sendMessage.setReplayMarkup(replyKeyboard); + sendMessage.setText(LocalisationService.getInstance().getString("backToMainMenu", language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + } + + // region Incoming messages handlers + + private static void handleIncomingMessage(Message message) { + final int state = DatabaseManager.getInstance().getWeatherState(message.getFrom().getId(), message.getChatId()); + final String language = DatabaseManager.getInstance().getUserWeatherOptions(message.getFrom().getId())[0]; + switch(state) { + case MAINMENU: + messageOnMainMenu(message, language); + break; + case CURRENTWEATHER: + case CURRENTNEWWEATHER: + case CURRENTLOCATIONWEATHER: + messageOnCurrentWeather(message, language, state); + break; + case FORECASTWEATHER: + case FORECASTNEWWEATHER: + case FORECASTLOCATIONWEATHER: + messageOnForecastWeather(message, language, state); + break; + case ALERT: + case ALERTNEW: + case ALERTDELETE: + messageOnAlert(message, language, state); + break; + case SETTINGS: + messageOnSetting(message, language); + break; + case LANGUAGE: + messageOnLanguage(message, language); + break; + case UNITS: + messageOnUnits(message, language); + break; + default: + sendMessageDefault(message, language); + break; + } + } + + // endregion Incoming messages handlers + + // region Alerts Menu Option selected + + private static void messageOnAlert(Message message, String language, int state) { + switch(state) { + case ALERT: + onAlertOptionSelected(message, language); + break; + case ALERTNEW: + onAlertNewOptionSelected(message, language); + break; + case ALERTDELETE: + onAlertDeleteOptionSelected(message, language); + break; + } + } + + private static void onAlertDeleteOptionSelected(Message message, String language) { + if (message.hasText()) { + if (message.getText().equals(getCancelCommand(language))) { + onAlertDeleteBackOptionSelected(message, language); + } else if (DatabaseManager.getInstance().getAlertCitiesNameByUser(message.getFrom().getId()).contains(message.getText())) { + onAlertDeleteCityOptionSelected(message, language); } else { - String language = DatabaseManager.getInstance().getUserLanguage(update.getMessage().getFrom().getId()); - String text = message.getText(); - String[] parts = text.split(" ", 2); - if (message.getText().startsWith(Commands.setLanguageCommand)) { - onSetLanguageCommand(message, language); - } else if (parts[0].startsWith(Commands.WEATHERCOMMAND)) { - if (parts.length == 2) { - onWeatherWithParameter(update, message, language, parts[1].split("-->", 2)[0]); - } else { - onWeatherWithoutParameters(message, language); - } - } else if (parts[0].startsWith(Commands.CURRENTWEATHERCOMMAND)) { - if (parts.length == 2) { - onCurrentWithParameters(update, message, language, parts[1].split("-->", 2)[0]); - } else { - onCurrentWithoutParameters(message, language); - } - } else if (message.isReply() && listOfSentMessages.containsKey(message.getReplyToMessage().getMessageId())) { - onReplyForPreviousCommnad(update, message, language); - } else if (parts[0].startsWith(Commands.help) || - (message.getText().startsWith(Commands.startCommand) || !message.isGroupMessage())) { - sendHelpMessage(message, language); - } + sendChooseOptionMessage(message.getChatId(), message.getMessageId(), getAlertsListKeyboard(message.getFrom().getId(), language), language); } - } else if (message != null && message.hasLocation()) { - onLocationReceived(update, message); } } - private void onLocationReceived(Update update, Message message) { - String language = DatabaseManager.getInstance().getUserLanguage(update.getMessage().getFrom().getId()); - String weather = WeatherService.getInstance().fetchWeatherForecastByLocation(message.getLocation().getLongitude(), - message.getLocation().getLatitude(), message.getFrom().getId(), language); + private static void onAlertDeleteCityOptionSelected(Message message, String language) { + DatabaseManager.getInstance().deleteAlertCity(message.getFrom().getId(), message.getText()); + SendMessage sendMessage = new SendMessage(); + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setChatId(message.getChatId()); + sendMessage.setReplayMarkup(getAlertsKeyboard(language)); + sendMessage.setText(LocalisationService.getInstance().getString("alertDeleted", language)); + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), ALERT); + } + + private static void onAlertDeleteBackOptionSelected(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setChatId(message.getChatId()); + sendMessage.setReplayMarkup(getAlertsKeyboard(language)); + sendMessage.setText(LocalisationService.getInstance().getString("alertsMenuMessage", language)); + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), ALERT); + } + + private static void onAlertNewOptionSelected(Message message, String language) { + if (message.hasText()) { + if (message.getText().equals(getCancelCommand(language))) { + SendMessage sendMessage = new SendMessage(); + sendMessage.setChatId(message.getChatId()); + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setReplayMarkup(getAlertsKeyboard(language)); + sendMessage.setText(LocalisationService.getInstance().getString("alertsMenuMessage", language)); + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), ALERT); + } else { + onNewAlertCityReceived(message, language); + } + } + } + + private static void onNewAlertCityReceived(Message message, String language) { + int userId = message.getFrom().getId(); + Integer cityId = DatabaseManager.getInstance().getRecentWeatherIdByCity(userId, message.getText()); + if (cityId != null) { + DatabaseManager.getInstance().createNewWeatherAlert(userId, cityId, message.getText()); + SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.setReplayMarkup(getAlertsKeyboard(language)); + sendMessageRequest.setReplayToMessageId(message.getMessageId()); + sendMessageRequest.setText(getChooseNewAlertSetMessage(message.getText(), language)); + sendMessageRequest.setChatId(message.getChatId()); + sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(userId, message.getChatId(), ALERT); + } else { + sendChooseOptionMessage(message.getChatId(), message.getMessageId(), + getRecentsKeyboard(message.getFrom().getId(), language, false), language); + } + } + + private static void onAlertOptionSelected(Message message, String language) { + if (message.hasText()) { + if (message.getText().equals(getNewCommand(language))) { + onNewAlertCommand(message, language); + } else if (message.getText().equals(getDeleteCommand(language))) { + onDeleteAlertCommand(message, language); + } else if (message.getText().equals(getListCommand(language))) { + onListAlertCommand(message, language); + } else if (message.getText().equals(getBackCommand(language))) { + onBackAlertCommand(message, language); + } else { + sendChooseOptionMessage(message.getChatId(), message.getMessageId(), + getAlertsKeyboard(language), language); + } + } + } + + private static void onBackAlertCommand(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + ReplyKeyboardMarkup replyKeyboardMarkup = getSettingsKeyboard(language); + sendMessage.setReplayMarkup(replyKeyboardMarkup); + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setChatId(message.getChatId()); + sendMessage.setText(getSettingsMessage(language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), SETTINGS); + } + + private static void onListAlertCommand(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + sendMessage.setChatId(message.getChatId()); + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setReplayMarkup(getAlertsKeyboard(language)); + sendMessage.setText(getAlertListMessage(message.getFrom().getId(), language)); + sendMessage.setReplayToMessageId(message.getMessageId()); + + sendBuiltMessage(sendMessage); + } + + private static void onDeleteAlertCommand(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + sendMessage.setChatId(message.getChatId()); + + ReplyKeyboardMarkup replyKeyboardMarkup = getAlertsListKeyboard(message.getFrom().getId(), language); + if (replyKeyboardMarkup != null) { + sendMessage.setReplayMarkup(replyKeyboardMarkup); + sendMessage.setText(LocalisationService.getInstance().getString("chooseNewAlertCity", language)); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), ALERTDELETE); + } else { + sendMessage.setReplayMarkup(getAlertsKeyboard(language)); + sendMessage.setText(LocalisationService.getInstance().getString("noAlertList", language)); + } + + sendMessage.setReplayToMessageId(message.getMessageId()); + sendBuiltMessage(sendMessage); + } + + private static void onNewAlertCommand(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + sendMessage.setChatId(message.getChatId()); + sendMessage.setReplayMarkup(getRecentsKeyboard(message.getFrom().getId(), language, false)); + sendMessage.setText(LocalisationService.getInstance().getString("chooseNewAlertCity", language)); + sendMessage.setReplayToMessageId(message.getMessageId()); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), ALERTNEW); + } + + // endregion Alerts Menu Option selected + + // region Settings Menu Option selected + + private static void messageOnSetting(Message message, String language) { + if (message.hasText()) { + if (message.getText().startsWith(getLanguagesCommand(language))) { + onLanguageCommand(message, language); + } else if (message.getText().startsWith(getUnitsCommand(language))) { + onUnitsCommand(message, language); + } else if (message.getText().startsWith(getAlertsCommand(language))) { + onAlertsCommand(message, language); + } else if (message.getText().startsWith(getBackCommand(language))) { + sendMessageDefault(message, language); + } else { + sendChooseOptionMessage(message.getChatId(), message.getMessageId(), + getSettingsKeyboard(language), language); + } + } + } + + private static void onAlertsCommand(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setChatId(message.getChatId()); + sendMessage.setReplayMarkup(getAlertsKeyboard(language)); + sendMessage.setText(LocalisationService.getInstance().getString("alertsMenuMessage", language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), ALERT); + } + + private static void onUnitsCommand(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setChatId(message.getChatId()); + sendMessage.setReplayMarkup(getUnitsKeyboard(language)); + sendMessage.setText(getUnitsMessage(message.getFrom().getId(), language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), UNITS); + } + + private static void onLanguageCommand(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setChatId(message.getChatId()); + sendMessage.setReplayMarkup(getLanguagesKeyboard(language)); + sendMessage.setText(getLanguageMessage(language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), LANGUAGE); + } + + // endregion Settings Menu Option selected + + // region Units Menu Option selected + + private static void messageOnUnits(Message message, String language) { + if (message.hasText()) { + if (message.getText().trim().equals(getCancelCommand(language))) { + onBackUnitsCommand(message, language); + } else if (message.getText().trim().equals(LocalisationService.getInstance().getString("metricSystem", language))) { + onUnitsChosen(message.getFrom().getId(), message.getChatId(), + message.getMessageId(), WeatherService.METRICSYSTEM, language); + } else if (message.getText().trim().equals(LocalisationService.getInstance().getString("imperialSystem", language))) { + onUnitsChosen(message.getFrom().getId(), message.getChatId(), + message.getMessageId(), WeatherService.IMPERIALSYSTEM, language); + } else { + onUnitsError(message.getChatId(), message.getMessageId(), language); + } + } + } + + private static void onBackUnitsCommand(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + ReplyKeyboardMarkup replyKeyboardMarkup = getSettingsKeyboard(language); + sendMessage.setReplayMarkup(replyKeyboardMarkup); + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setChatId(message.getChatId()); + sendMessage.setText(getSettingsMessage(language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), SETTINGS); + } + + private static void onUnitsError(Integer chatId, Integer messageId, String language) { SendMessage sendMessageRequest = new SendMessage(); - ReplyKeyboardHide replyKeyboardHide = new ReplyKeyboardHide(); - replyKeyboardHide.setSelective(true); - replyKeyboardHide.setHideKeyboard(true); - sendMessageRequest.setReplayMarkup(replyKeyboardHide); - sendMessageRequest.setReplayToMessageId(update.getMessage().getMessageId()); - sendMessageRequest.setText(weather); - sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + sendMessageRequest.setChatId(chatId); + sendMessageRequest.setReplayMarkup(getUnitsKeyboard(language)); + sendMessageRequest.setText(LocalisationService.getInstance().getString("errorUnitsNotFound", language)); + sendMessageRequest.setReplayToMessageId(messageId); + sendBuiltMessage(sendMessageRequest); } - private void sendHelpMessage(Message message, String language) { + private static void onUnitsChosen(Integer userId, Integer chatId, Integer messageId, String units, String language) { + DatabaseManager.getInstance().putUserWeatherUnitsOption(userId, units); + SendMessage sendMessageRequest = new SendMessage(); - String formatedHelp = String.format( - LocalisationService.getInstance().getString("helpWeather", language), - Commands.WEATHERCOMMAND, Commands.CURRENTWEATHERCOMMAND); - sendMessageRequest.setText(formatedHelp); - sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + sendMessageRequest.setChatId(chatId); + sendMessageRequest.setText(LocalisationService.getInstance().getString("unitsUpdated", language)); + sendMessageRequest.setReplayToMessageId(messageId); + sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); + sendBuiltMessage(sendMessageRequest); + + DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); } - private void onReplyForPreviousCommnad(Update update, Message message, String language) { + // endregion Units Menu Option selected + + // region Language Menu Option selected + + private static void messageOnLanguage(Message message, String language) { + if (message.hasText()) { + if (message.getText().trim().equals(getCancelCommand(language))) { + onBackLanguageCommand(message, language); + } else if (LocalisationService.getInstance().getSupportedLanguages().values().contains(message.getText().trim())) { + onLanguageChosen(message.getFrom().getId(), message.getChatId(), + message.getMessageId(), message.getText().trim()); + } else { + onLanguageError(message.getChatId(), message.getMessageId(), language); + } + } + } + + private static void onBackLanguageCommand(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + ReplyKeyboardMarkup replyKeyboardMarkup = getSettingsKeyboard(language); + sendMessage.setReplayMarkup(replyKeyboardMarkup); + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setChatId(message.getChatId()); + sendMessage.setText(getSettingsMessage(language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), SETTINGS); + } + + private static void onLanguageError(Integer chatId, Integer messageId, String language) { SendMessage sendMessageRequest = new SendMessage(); - if (listOfSentMessages.remove(message.getReplyToMessage().getMessageId()) == CURRENTWEATHERID) { - String weather = WeatherService.getInstance().fetchWeatherCurrent(message.getText(), - message.getFrom().getId(), language); - sendMessageRequest.setText(weather); + sendMessageRequest.setChatId(chatId); + sendMessageRequest.setReplayMarkup(getLanguagesKeyboard(language)); + sendMessageRequest.setText(LocalisationService.getInstance().getString("errorLanguageNotFound", language)); + sendMessageRequest.setReplayToMessageId(messageId); + sendBuiltMessage(sendMessageRequest); + } + + private static void onLanguageChosen(Integer userId, Integer chatId, Integer messageId, String language) { + String languageCode = LocalisationService.getInstance().getLanguageCodeByName(language); + DatabaseManager.getInstance().putUserWeatherLanguageOption(userId, languageCode); + + SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.setChatId(chatId); + sendMessageRequest.setText(LocalisationService.getInstance().getString("languageUpdated", languageCode)); + sendMessageRequest.setReplayToMessageId(messageId); + sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(languageCode)); + sendBuiltMessage(sendMessageRequest); + + DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + } + + // endregion Language Menu Option selected + + // region Forecast Weather Menu Option selected + + private static void messageOnForecastWeather(Message message, String language, int state) { + switch(state) { + case FORECASTWEATHER: + onForecastWeather(message, language); + break; + case FORECASTNEWWEATHER: + onForecastNewWeather(message, language); + break; + case FORECASTLOCATIONWEATHER: + onForecastWeatherLocation(message, language); + break; + } + } + + private static void onForecastWeather(Message message, String language) { + if (message.hasText()) { + if (message.getText().startsWith(getNewCommand(language))) { + onNewForecastWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); + } else if (message.getText().startsWith(getLocationCommand(language))) { + onLocationForecastWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); + } else if (message.getText().startsWith(getCancelCommand(language))) { + onCancelCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), + getMainMenuKeyboard(language), language); + } else { + onForecastWeatherCityReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), + message.getText(), language); + } + } + } + + private static void onForecastNewWeather(Message message, String language) { + if (message.isReply()) { + onForecastWeatherReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), message.getText(), language); } else { - String weather = WeatherService.getInstance().fetchWeatherForecast(message.getText(), - message.getFrom().getId(), language); + sendMessageDefault(message, language); + } + } + + private static void onForecastWeatherCityReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { + Integer cityId = DatabaseManager.getInstance().getRecentWeatherIdByCity(userId, text); + if (cityId != null) { + String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(userId)[1]; + String weather = WeatherService.getInstance().fetchWeatherForecast(cityId.toString(), userId, language, unitsSystem); + SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); + sendMessageRequest.setReplayToMessageId(messageId); sendMessageRequest.setText(weather); + sendMessageRequest.setChatId(chatId); + sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + } else { + sendChooseOptionMessage(chatId, messageId, getRecentsKeyboard(userId, language), language); } - ReplyKeyboardHide replyKeyboardHide = new ReplyKeyboardHide(); - replyKeyboardHide.setSelective(true); - replyKeyboardHide.setHideKeyboard(true); - sendMessageRequest.setReplayMarkup(replyKeyboardHide); - sendMessageRequest.setReplayToMessageId(update.getMessage().getMessageId()); - sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); } - private void onCurrentWithoutParameters(Message message, String language) { - HashMap recentWeather = DatabaseManager.getInstance().getRecentWeather(message.getFrom().getId()); - SendMessage sendMessageRequest = new SendMessage(); - if (recentWeather.size() > 0) { - ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup(); - List> commands = new ArrayList<>(); - for (Map.Entry entry : recentWeather.entrySet()) { - List commandRow = new ArrayList<>(); - commandRow.add(Commands.CURRENTWEATHERCOMMAND + " " + entry.getKey() + " --> " + entry.getValue()); - commands.add(commandRow); + private static void onLocationForecastWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { + ForceReplyKeyboard forceReplyKeyboard = getForceReply(); + + SendMessage sendMessage = new SendMessage(); + sendMessage.setChatId(chatId); + sendMessage.setReplayToMessageId(messageId); + sendMessage.setReplayMarkup(forceReplyKeyboard); + sendMessage.setText(LocalisationService.getInstance().getString("onWeatherLocationCommand", language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, FORECASTLOCATIONWEATHER); + } + + private static void onNewForecastWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { + ForceReplyKeyboard forceReplyKeyboard = getForceReply(); + + SendMessage sendMessage = new SendMessage(); + sendMessage.setChatId(chatId); + sendMessage.setReplayToMessageId(messageId); + sendMessage.setReplayMarkup(forceReplyKeyboard); + sendMessage.setText(LocalisationService.getInstance().getString("onWeatherNewCommand", language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, FORECASTNEWWEATHER); + } + + private static void onForecastWeatherLocation(Message message, String language) { + if (message.isReply() && message.hasLocation()) { + onForecastWeatherLocationReceived(message, language); + } else { + sendMessageDefault(message, language); + } + } + + // endregion Forecast Weather Menu Option selected + + // region Current Weather Menu Option selected + + private static void messageOnCurrentWeather(Message message, String language, int state) { + switch(state) { + case CURRENTWEATHER: + onCurrentWeather(message, language); + break; + case CURRENTNEWWEATHER: + onCurrentNewWeather(message, language); + break; + case CURRENTLOCATIONWEATHER: + onCurrentWeatherLocation(message, language); + break; + } + } + + private static void onCurrentWeather(Message message, String language) { + if (message.hasText()) { + if (message.getText().startsWith(getNewCommand(language))) { + onNewCurrentWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); + } else if (message.getText().startsWith(getLocationCommand(language))) { + onLocationCurrentWeatherCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), language); + } else if (message.getText().startsWith(getCancelCommand(language))) { + onCancelCommand(message.getChatId(), message.getFrom().getId(), message.getMessageId(), + getMainMenuKeyboard(language), language); + } else { + onCurrentWeatherCityReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), + message.getText(), language); } - replyKeyboardMarkup.setResizeKeyboard(true); - replyKeyboardMarkup.setOneTimeKeyboad(true); - replyKeyboardMarkup.setSelective(true); - replyKeyboardMarkup.setKeyboard(commands); - sendMessageRequest.setReplayMarkup(replyKeyboardMarkup); - sendMessageRequest.setText(LocalisationService.getInstance().getString("chooseFromRecentWeather", language)); + } + } + + private static void onCurrentNewWeather(Message message, String language) { + if (message.isReply()) { + onCurrentWeatherReceived(message.getChatId(), message.getFrom().getId(), message.getMessageId(), message.getText(), language); } else { - sendMessageRequest.setText(LocalisationService.getInstance().getString("pleaseSendMeCityWeather", language)); - ForceReply forceReply = new ForceReply(); - forceReply.setForceReply(true); - forceReply.setSelective(true); - sendMessageRequest.setReplayMarkup(forceReply); + sendMessageDefault(message, language); } - sendMessageRequest.setChatId(message.getChatId()); - sendMessageRequest.setReplayToMessageId(message.getMessageId()); - Message sentMessage = SenderHelper.SendMessage(sendMessageRequest, TOKEN); - try { - listOfSentMessages.put(sentMessage.getMessageId(), CURRENTWEATHERID); - } catch (NullPointerException e) { - log.error(e); + } + + private static void onCurrentWeatherCityReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { + Integer cityId = DatabaseManager.getInstance().getRecentWeatherIdByCity(userId, text); + if (cityId != null) { + String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(userId)[1]; + String weather = WeatherService.getInstance().fetchWeatherCurrent(cityId.toString(), userId, language, unitsSystem); + SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); + sendMessageRequest.setReplayToMessageId(messageId); + sendMessageRequest.setText(weather); + sendMessageRequest.setChatId(chatId); + sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + } else { + sendChooseOptionMessage(chatId, messageId, getRecentsKeyboard(userId, language), language); } } - private void onCurrentWithParameters(Update update, Message message, String language, String s) { - String citywithoutdescription = s.trim(); - String weather = WeatherService.getInstance().fetchWeatherCurrent(citywithoutdescription, - message.getFrom().getId(), language); - SendMessage sendMessageRequest = new SendMessage(); - ReplyKeyboardHide replyKeyboardHide = new ReplyKeyboardHide(); - replyKeyboardHide.setSelective(true); - replyKeyboardHide.setHideKeyboard(true); - sendMessageRequest.setReplayMarkup(replyKeyboardHide); - sendMessageRequest.setReplayToMessageId(update.getMessage().getMessageId()); - sendMessageRequest.setText(weather); - sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + private static void onLocationCurrentWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { + ForceReplyKeyboard forceReplyKeyboard = getForceReply(); + + SendMessage sendMessage = new SendMessage(); + sendMessage.setChatId(chatId); + sendMessage.setReplayToMessageId(messageId); + sendMessage.setReplayMarkup(forceReplyKeyboard); + sendMessage.setText(LocalisationService.getInstance().getString("onWeatherLocationCommand", language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, CURRENTLOCATIONWEATHER); } - private void onWeatherWithoutParameters(Message message, String language) { - HashMap recentWeather = DatabaseManager.getInstance().getRecentWeather(message.getFrom().getId()); - SendMessage sendMessageRequest = new SendMessage(); - if (recentWeather.size() > 0) { - ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup(); - List> commands = new ArrayList<>(); - for (Map.Entry entry : recentWeather.entrySet()) { - List commandRow = new ArrayList<>(); - commandRow.add(Commands.WEATHERCOMMAND + " " + entry.getKey() + " --> " + entry.getValue()); - commands.add(commandRow); + private static void onNewCurrentWeatherCommand(Integer chatId, Integer userId, Integer messageId, String language) { + ForceReplyKeyboard forceReplyKeyboard = getForceReply(); + + SendMessage sendMessage = new SendMessage(); + sendMessage.setChatId(chatId); + sendMessage.setReplayToMessageId(messageId); + sendMessage.setReplayMarkup(forceReplyKeyboard); + sendMessage.setText(LocalisationService.getInstance().getString("onWeatherNewCommand", language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, CURRENTNEWWEATHER); + } + + private static void onCurrentWeatherLocation(Message message, String language) { + if (message.isReply() && message.hasLocation()) { + onCurrentWeatherLocationReceived(message, language); + } else { + sendMessageDefault(message, language); + } + } + + // endregion Current Weather Menu Option selected + + // region Main menu options selected + + private static void messageOnMainMenu(Message message, String language) { + if (message.hasText()) { + if (message.getText().equals(getCurrentCommand(language))) { + onCurrentChoosen(message, language); + } else if (message.getText().equals(getForecastCommand(language))) { + onForecastChoosen(message, language); + } else if (message.getText().equals(getSettingsCommand(language))) { + onSettingsChoosen(message, language); + } else if (message.getText().equals(getRateCommand(language))) { + sendRateMessage(message.getChatId(), message.getMessageId(), null, language); + } else { + sendChooseOptionMessage(message.getChatId(), message.getMessageId(), + getMainMenuKeyboard(language), language); } - replyKeyboardMarkup.setResizeKeyboard(true); - replyKeyboardMarkup.setOneTimeKeyboad(true); - replyKeyboardMarkup.setSelective(true); - replyKeyboardMarkup.setKeyboard(commands); - sendMessageRequest.setReplayMarkup(replyKeyboardMarkup); - sendMessageRequest.setText(LocalisationService.getInstance().getString("chooseFromRecentWeather", language)); } else { - sendMessageRequest.setText(LocalisationService.getInstance().getString("pleaseSendMeCityWeather", language)); - ForceReply forceReply = new ForceReply(); - forceReply.setForceReply(true); - forceReply.setSelective(true); - sendMessageRequest.setReplayMarkup(forceReply); + sendChooseOptionMessage(message.getChatId(), message.getMessageId(), + getMainMenuKeyboard(language), language); } - sendMessageRequest.setReplayToMessageId(message.getMessageId()); - sendMessageRequest.setChatId(message.getChatId()); - Message sentMessage = SenderHelper.SendMessage(sendMessageRequest, TOKEN); - try { - listOfSentMessages.put(sentMessage.getMessageId(), FORECASTWEATHERID); - } catch (NullPointerException e) { - log.error(e); + } + + private static void onSettingsChoosen(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + ReplyKeyboardMarkup replyKeyboardMarkup = getSettingsKeyboard(language); + sendMessage.setReplayMarkup(replyKeyboardMarkup); + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setChatId(message.getChatId()); + sendMessage.setText(getSettingsMessage(language)); + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), SETTINGS); + } + + private static void onForecastChoosen(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + ReplyKeyboardMarkup replyKeyboardMarkup = getRecentsKeyboard(message.getFrom().getId(), language); + sendMessage.setReplayMarkup(replyKeyboardMarkup); + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setChatId(message.getChatId()); + if (replyKeyboardMarkup.getKeyboard().size() > 3) { + sendMessage.setText(LocalisationService.getInstance().getString("onForecastCommandFromHistory", language)); + } else { + sendMessage.setText(LocalisationService.getInstance().getString("onForecastCommandWithoutHistory", language)); } + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), FORECASTWEATHER); } - private void onWeatherWithParameter(Update update, Message message, String language, String s) { - String citywithoutdescription = s.trim(); - String weather = WeatherService.getInstance().fetchWeatherForecast(citywithoutdescription, - message.getFrom().getId(), language); - SendMessage sendMessageRequest = new SendMessage(); - ReplyKeyboardHide replyKeyboardHide = new ReplyKeyboardHide(); - replyKeyboardHide.setSelective(true); - replyKeyboardHide.setHideKeyboard(true); - sendMessageRequest.setReplayMarkup(replyKeyboardHide); - sendMessageRequest.setReplayToMessageId(update.getMessage().getMessageId()); - sendMessageRequest.setText(weather); - sendMessageRequest.setChatId(message.getChatId()); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); + private static void onCurrentChoosen(Message message, String language) { + SendMessage sendMessage = new SendMessage(); + + ReplyKeyboardMarkup replyKeyboardMarkup = getRecentsKeyboard(message.getFrom().getId(), language); + sendMessage.setReplayMarkup(replyKeyboardMarkup); + sendMessage.setReplayToMessageId(message.getMessageId()); + sendMessage.setChatId(message.getChatId()); + if (replyKeyboardMarkup.getKeyboard().size() > 3) { + sendMessage.setText(LocalisationService.getInstance().getString("onCurrentCommandFromHistory", language)); + } else { + sendMessage.setText(LocalisationService.getInstance().getString("onCurrentCommandWithoutHistory", language)); + } + + sendBuiltMessage(sendMessage); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), CURRENTWEATHER); } - private void onSetLanguageCommand(Message message, String language) { - SendMessage sendMessageRequest = new SendMessage(); - sendMessageRequest.setChatId(message.getChatId()); + // endregion Main menu options selected + + // region Get Messages + + private static String getSettingsMessage(String language) { + String baseString = LocalisationService.getInstance().getString("onSettingsCommand", language); + return String.format(baseString, Emoji.GLOBE_WITH_MERIDIANS.toString(), + Emoji.STRAIGHT_RULER.toString(), Emoji.ALARM_CLOCK.toString(), + Emoji.BACK_WITH_LEFTWARDS_ARROW_ABOVE.toString()); + } + + private static String getHelpMessage(String language) { + String baseString = LocalisationService.getInstance().getString("helpWeatherMessage", language); + return String.format(baseString, Emoji.BLACK_RIGHT_POINTING_TRIANGLE.toString(), + Emoji.BLACK_RIGHT_POINTING_DOUBLE_TRIANGLE.toString(), Emoji.ALARM_CLOCK.toString(), + Emoji.EARTH_GLOBE_EUROPE_AFRICA.toString(), Emoji.STRAIGHT_RULER.toString()); + } + + private static String getLanguageMessage(String language) { + String baseString = LocalisationService.getInstance().getString("selectLanguage", language); + return String.format(baseString, language); + } + + private static String getUnitsMessage(Integer userId, String language) { + String baseString = LocalisationService.getInstance().getString("selectUnits", language); + return String.format(baseString, DatabaseManager.getInstance().getUserWeatherOptions(userId)[1]); + } + + private static String getChooseNewAlertSetMessage(String city, String language) { + String baseString = LocalisationService.getInstance().getString("newAlertSaved", language); + return String.format(baseString, Emoji.THUMBS_UP_SIGN.toString(), city); + } + + private static String getAlertListMessage(int userId, String language) { + String alertListMessage; + + List alertCities = DatabaseManager.getInstance().getAlertCitiesNameByUser(userId); + if (alertCities.size() > 0) { + String baseAlertListString = LocalisationService.getInstance().getString("initialAlertList", language); + String partialAlertListString = LocalisationService.getInstance().getString("partialAlertList", language); + String fullListOfAlerts = ""; + for (String alertCity : alertCities) { + fullListOfAlerts += String.format(partialAlertListString, Emoji.ALARM_CLOCK.toString(), alertCity); + } + alertListMessage = String.format(baseAlertListString, alertCities.size(), fullListOfAlerts); + } else { + alertListMessage = LocalisationService.getInstance().getString("noAlertList", language); + } + + return alertListMessage; + } + + + // endregion Get Messages + + // region ReplyKeyboards + + private static ReplyKeyboardMarkup getMainMenuKeyboard(String language) { ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup(); - HashMap languages = LocalisationService.getInstance().supportedLanguages; - List> commands = new ArrayList<>(); - for (Map.Entry entry : languages.entrySet()) { - List commandRow = new ArrayList<>(); - commandRow.add(entry.getKey() + " --> " + entry.getValue()); - commands.add(commandRow); + replyKeyboardMarkup.setSelective(true); + replyKeyboardMarkup.setResizeKeyboard(true); + replyKeyboardMarkup.setOneTimeKeyboad(false); + + List> keyboard = new ArrayList<>(); + List keyboardFirstRow = new ArrayList<>(); + keyboardFirstRow.add(getCurrentCommand(language)); + keyboardFirstRow.add(getForecastCommand(language)); + List keyboardSecondRow = new ArrayList<>(); + keyboardSecondRow.add(getSettingsCommand(language)); + keyboardSecondRow.add(getRateCommand(language)); + keyboard.add(keyboardFirstRow); + keyboard.add(keyboardSecondRow); + replyKeyboardMarkup.setKeyboard(keyboard); + + return replyKeyboardMarkup; + } + + private static ReplyKeyboardMarkup getLanguagesKeyboard(String language) { + ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup(); + replyKeyboardMarkup.setSelective(true); + replyKeyboardMarkup.setResizeKeyboard(true); + replyKeyboardMarkup.setOneTimeKeyboad(false); + + List> keyboard = new ArrayList<>(); + for (String languageName : LocalisationService.getInstance().getSupportedLanguages().values()) { + List row = new ArrayList<>(); + row.add(languageName); + keyboard.add(row); } + + List row = new ArrayList<>(); + row.add(getCancelCommand(language)); + keyboard.add(row); + replyKeyboardMarkup.setKeyboard(keyboard); + + return replyKeyboardMarkup; + } + + private static ReplyKeyboardMarkup getUnitsKeyboard(String language) { + ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup(); + replyKeyboardMarkup.setSelective(true); + replyKeyboardMarkup.setResizeKeyboard(true); + replyKeyboardMarkup.setOneTimeKeyboad(false); + + List> keyboard = new ArrayList<>(); + List row = new ArrayList<>(); + row.add(LocalisationService.getInstance().getString("metricSystem", language)); + keyboard.add(row); + row = new ArrayList<>(); + row.add(LocalisationService.getInstance().getString("imperialSystem", language)); + keyboard.add(row); + row = new ArrayList<>(); + row.add(getCancelCommand(language)); + keyboard.add(row); + replyKeyboardMarkup.setKeyboard(keyboard); + + return replyKeyboardMarkup; + } + + private static ReplyKeyboardMarkup getSettingsKeyboard(String language) { + ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup(); + replyKeyboardMarkup.setSelective(true); + replyKeyboardMarkup.setResizeKeyboard(true); + replyKeyboardMarkup.setOneTimeKeyboad(false); + + List> keyboard = new ArrayList<>(); + List keyboardFirstRow = new ArrayList<>(); + keyboardFirstRow.add(getLanguagesCommand(language)); + keyboardFirstRow.add(getUnitsCommand(language)); + List keyboardSecondRow = new ArrayList<>(); + keyboardSecondRow.add(getAlertsCommand(language)); + keyboardSecondRow.add(getBackCommand(language)); + keyboard.add(keyboardFirstRow); + keyboard.add(keyboardSecondRow); + replyKeyboardMarkup.setKeyboard(keyboard); + + return replyKeyboardMarkup; + } + + private static ReplyKeyboardMarkup getRecentsKeyboard(Integer userId, String language) { + return getRecentsKeyboard(userId, language, true); + } + + private static ReplyKeyboardMarkup getRecentsKeyboard(Integer userId, String language, boolean allowNew) { + ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup(); + replyKeyboardMarkup.setSelective(true); replyKeyboardMarkup.setResizeKeyboard(true); replyKeyboardMarkup.setOneTimeKeyboad(true); - replyKeyboardMarkup.setKeyboard(commands); + + List> keyboard = new ArrayList<>(); + for (String recentWeather : DatabaseManager.getInstance().getRecentWeather(userId)) { + List row = new ArrayList<>(); + row.add(recentWeather); + keyboard.add(row); + } + + List row = new ArrayList<>(); + if (allowNew) { + row.add(getLocationCommand(language)); + keyboard.add(row); + + row = new ArrayList<>(); + row.add(getNewCommand(language)); + keyboard.add(row); + + row = new ArrayList<>(); + } + row.add(getCancelCommand(language)); + keyboard.add(row); + + replyKeyboardMarkup.setKeyboard(keyboard); + + return replyKeyboardMarkup; + } + + private static ReplyKeyboardMarkup getAlertsKeyboard(String language) { + ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup(); replyKeyboardMarkup.setSelective(true); - sendMessageRequest.setReplayMarkup(replyKeyboardMarkup); - sendMessageRequest.setReplayToMessageId(message.getMessageId()); - sendMessageRequest.setText(LocalisationService.getInstance().getString("chooselanguage", language)); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); - languageMessages.add(message.getFrom().getId()); + replyKeyboardMarkup.setResizeKeyboard(true); + replyKeyboardMarkup.setOneTimeKeyboad(true); + + List> keyboard = new ArrayList<>(); + + List row = new ArrayList<>(); + row.add(getNewCommand(language)); + row.add(getDeleteCommand(language)); + keyboard.add(row); + + row = new ArrayList<>(); + row.add(getListCommand(language)); + row.add(getBackCommand(language)); + keyboard.add(row); + + replyKeyboardMarkup.setKeyboard(keyboard); + + return replyKeyboardMarkup; + } + + private static ReplyKeyboardMarkup getAlertsListKeyboard(Integer userId, String language) { + ReplyKeyboardMarkup replyKeyboardMarkup = null; + + List alertCitiesNames = DatabaseManager.getInstance().getAlertCitiesNameByUser(userId); + if (alertCitiesNames.size() > 0) { + replyKeyboardMarkup = new ReplyKeyboardMarkup(); + replyKeyboardMarkup.setSelective(true); + replyKeyboardMarkup.setResizeKeyboard(true); + replyKeyboardMarkup.setOneTimeKeyboad(true); + + List> keyboard = new ArrayList<>(); + for (String alertCityName: alertCitiesNames) { + List row = new ArrayList<>(); + row.add(alertCityName); + keyboard.add(row); + } + List row = new ArrayList<>(); + row.add(getCancelCommand(language)); + keyboard.add(row); + + replyKeyboardMarkup.setKeyboard(keyboard); + } + + return replyKeyboardMarkup; + } + + private static ForceReplyKeyboard getForceReply() { + ForceReplyKeyboard forceReplyKeyboard = new ForceReplyKeyboard(); + forceReplyKeyboard.setForceReply(true); + forceReplyKeyboard.setSelective(true); + return forceReplyKeyboard; + } + + // endregion ReplyKeyboards + + // region getCommnads + + private static String getRateCommand(String language) { + return String.format(LocalisationService.getInstance().getString("rateMe", language), + Emoji.HUNDRED_POINTS_SYMBOL.toString()); + } + + private static String getListCommand(String language) { + return String.format(LocalisationService.getInstance().getString("showList", language), + Emoji.CLIPBOARD.toString()); + } + + private static String getDeleteCommand(String language) { + return String.format(LocalisationService.getInstance().getString("delete", language), + Emoji.HEAVY_MINUS_SIGN.toString()); + } + + private static String getLanguagesCommand(String language) { + return String.format(LocalisationService.getInstance().getString("languages", language), + Emoji.GLOBE_WITH_MERIDIANS.toString()); + } + + private static String getUnitsCommand(String language) { + return String.format(LocalisationService.getInstance().getString("units", language), + Emoji.STRAIGHT_RULER.toString()); + } + + private static String getAlertsCommand(String language) { + return String.format(LocalisationService.getInstance().getString("alerts", language), + Emoji.ALARM_CLOCK.toString()); + } + + private static String getBackCommand(String language) { + return String.format(LocalisationService.getInstance().getString("back", language), + Emoji.BACK_WITH_LEFTWARDS_ARROW_ABOVE.toString()); + } + + private static String getNewCommand(String language) { + return String.format(LocalisationService.getInstance().getString("new", language), + Emoji.HEAVY_PLUS_SIGN.toString()); + } + + private static String getLocationCommand(String language) { + return String.format(LocalisationService.getInstance().getString("location", language), + Emoji.ROUND_PUSHPIN.toString()); + } + + private static String getSettingsCommand(String language) { + return String.format(LocalisationService.getInstance().getString("settings", language), + Emoji.WRENCH.toString()); } - private void onLanguageReceived(Message message) { - String[] parts = message.getText().split("-->", 2); + private static String getCurrentCommand(String language) { + return String.format(LocalisationService.getInstance().getString("current", language), + Emoji.BLACK_RIGHT_POINTING_TRIANGLE.toString()); + } + + private static String getHelpCommand(String language) { + return String.format(LocalisationService.getInstance().getString("help", language), + Emoji.BLACK_QUESTION_MARK_ORNAMENT.toString()); + } + + private static String getForecastCommand(String language) { + return String.format(LocalisationService.getInstance().getString("forecast", language), + Emoji.BLACK_RIGHT_POINTING_DOUBLE_TRIANGLE.toString()); + } + + private static String getCancelCommand(String language) { + return String.format(LocalisationService.getInstance().getString("cancel", language), + Emoji.CROSS_MARK.toString()); + } + // endregion getCommnads + + // region Send common messages + + private static void sendMessageDefault(Message message, String language) { + ReplyKeyboardMarkup replyKeyboardMarkup = getMainMenuKeyboard(language); + sendHelpMessage(message.getChatId(), message.getMessageId(), replyKeyboardMarkup, language); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), MAINMENU); + } + + private static void sendChooseOptionMessage(Integer chatId, Integer messageId, + ReplyKeyboard replyKeyboard, String language) { + SendMessage sendMessage = new SendMessage(); + sendMessage.setChatId(chatId); + sendMessage.setReplayToMessageId(messageId); + sendMessage.setReplayMarkup(replyKeyboard); + sendMessage.setText(LocalisationService.getInstance().getString("chooseOption", language)); + sendBuiltMessage(sendMessage); + } + + private static void sendHelpMessage(Integer chatId, Integer messageId, ReplyKeyboardMarkup replyKeyboardMarkup, String language) { + SendMessage sendMessage = new SendMessage(); + sendMessage.setChatId(chatId); + sendMessage.setReplayToMessageId(messageId); + if (replyKeyboardMarkup != null) { + sendMessage.setReplayMarkup(replyKeyboardMarkup); + } + sendMessage.setText(getHelpMessage(language)); + sendBuiltMessage(sendMessage); + } + + private static void sendRateMessage(Integer chatId, Integer messageId, ReplyKeyboardMarkup replyKeyboardMarkup, String language) { + SendMessage sendMessage = new SendMessage(); + sendMessage.setChatId(chatId); + sendMessage.setReplayToMessageId(messageId); + if (replyKeyboardMarkup != null) { + sendMessage.setReplayMarkup(replyKeyboardMarkup); + } + sendMessage.setText(LocalisationService.getInstance().getString("rateMeMessage", language)); + sendBuiltMessage(sendMessage); + } + + // endregion Send common messages + + // region Send weather + + private static void onForecastWeatherLocationReceived(Message message, String language) { + String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(message.getFrom().getId())[1]; + String weather = WeatherService.getInstance().fetchWeatherForecastByLocation(message.getLocation().getLongitude(), + message.getLocation().getLatitude(), message.getFrom().getId(), language, unitsSystem); SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); + sendMessageRequest.setReplayToMessageId(message.getMessageId()); + sendMessageRequest.setText(weather); sendMessageRequest.setChatId(message.getChatId()); - if (LocalisationService.getInstance().supportedLanguages.containsKey(parts[0].trim())) { - DatabaseManager.getInstance().putUserLanguage(message.getFrom().getId(), parts[0].trim()); - sendMessageRequest.setText(LocalisationService.getInstance().getString("languageModified", parts[0].trim())); - } else { - sendMessageRequest.setText(LocalisationService.getInstance().getString("errorLanguage")); - } + sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), MAINMENU); + } + + private static void onForecastWeatherReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { + String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(userId)[1]; + String weather = WeatherService.getInstance().fetchWeatherForecast(text, userId, language, unitsSystem); + SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); + sendMessageRequest.setReplayToMessageId(messageId); + sendMessageRequest.setText(weather); + sendMessageRequest.setChatId(chatId); + sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); + } + + private static void onCurrentWeatherLocationReceived(Message message, String language) { + String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(message.getFrom().getId())[1]; + String weather = WeatherService.getInstance().fetchWeatherCurrentByLocation(message.getLocation().getLongitude(), + message.getLocation().getLatitude(), message.getFrom().getId(), language, unitsSystem); + SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); sendMessageRequest.setReplayToMessageId(message.getMessageId()); - ReplyKeyboardHide replyKeyboardHide = new ReplyKeyboardHide(); - replyKeyboardHide.setHideKeyboard(true); - replyKeyboardHide.setSelective(true); - sendMessageRequest.setReplayMarkup(replyKeyboardHide); - SenderHelper.SendMessage(sendMessageRequest, TOKEN); - languageMessages.remove(message.getFrom().getId()); + sendMessageRequest.setText(weather); + sendMessageRequest.setChatId(message.getChatId()); + sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(message.getFrom().getId(), message.getChatId(), MAINMENU); + } + + private static void onCurrentWeatherReceived(Integer chatId, Integer userId, Integer messageId, String text, String language) { + String unitsSystem = DatabaseManager.getInstance().getUserWeatherOptions(userId)[1]; + String weather = WeatherService.getInstance().fetchWeatherCurrent(text, userId, language, unitsSystem); + SendMessage sendMessageRequest = new SendMessage(); + sendMessageRequest.setReplayMarkup(getMainMenuKeyboard(language)); + sendMessageRequest.setReplayToMessageId(messageId); + sendMessageRequest.setText(weather); + sendMessageRequest.setChatId(chatId); + sendBuiltMessage(sendMessageRequest); + DatabaseManager.getInstance().insertWeatherState(userId, chatId, MAINMENU); } + + // endregion Send weather + + // region Helper Methods + + private static void sendBuiltMessage(SendMessage sendMessage) { + SenderHelper.SendMessage(sendMessage, TOKEN); + } + + // endregion Helper Methods } diff --git a/src/main/resources/localisation/strings.properties b/src/main/resources/localisation/strings.properties index 1226e14..ee3d874 100644 --- a/src/main/resources/localisation/strings.properties +++ b/src/main/resources/localisation/strings.properties @@ -1,6 +1,5 @@ -helpWeather= Curious about the weather?\nJust send me these commands and you'll know a lot better.\n\n|-- %s CITY,COUNTRY : Get a 3-day weather forecast for a city.\n|-- %s CITY,COUNTRY : Get the current weather of a city.\n\n|-- Send a location to get the forecast for it. -helpTransifex= Tricks with words is the game that I play, give it a shot, I might make your day.\n\nTo get the latest Telegram localization file for a language: \n|-- %s LANG_CODE : Get the latest iOS language.\n|-- %s LANG_CODE : Get the latest android language.\n|-- %s LANG_CODE : Get the latest webogram language.\n|-- %s LANG_CODE : Get the latest Tdesktop language.\n|-- %s LANG_CODE : Get the latest OSX-App language.\n|-- %s LANG_CODE : Get the latest Windows Phone language.\n\n2. To get an updated localization file for your Android beta-app: \n|-- %s LANG_CODE : Get the latest Android-beta language. -helpFiles= Leaving a file for some others to find? Just dock your boat here and a bay comes to mind.\n\nShare files through a custom link: \n|-- %s FILEID : Get a file by id.\n|-- %s : Start your file upload.\n|-- %s : Choose one of your files to delete it.\n|-- %s : Show a list of your shared files. +helpTransifex= Tricks with words is the game that I play, give it a shot, I might make your day.\n\nTo get the latest Telegram localization file for a language: \n|-- %s LANG_CODE : Get the latest iOS language.\n|-- %s LANG_CODE : Get the latest Android language.\n|-- %s LANG_CODE : Get the latest Webogram language.\n|-- %s LANG_CODE : Get the latest Tdesktop language.\n|-- %s LANG_CODE : Get the latest OSX-App language.\n|-- %s LANG_CODE : Get the latest Windows Phone language.\n\n2. To get an updated localization file for your Android beta-app: \n|-- %s LANG_CODE : Get the latest Android-beta language. +helpFiles= Leaving a file for some others to find? Just dock your boat here and a bay comes to mind.\n\nShare files through a custom link: \n|-- %s FILEID : Get a file by id.\n|-- %s : Start your file upload.\n|-- %s : Select one of your files to delete it.\n|-- %s : Show a list of your shared files. helpDirections= The road ahead, paved with good intentions, the right path ahead however, is what I tend to mention.\n\nTo get directions between two locations: \n|-- %s : Start to get directions sendFileToUpload= Please send me a file you want to share. Make sure you attach it as file, not as an image or video. fileUploaded= Great, your file has been uploaded. Send this link to anyone you want and they will be able to download the file:\n\n @@ -11,21 +10,76 @@ listOfFiles= This your currently shared list of files: noFiles= You haven't shared any files yet. processFinished= The current process was cancelled. uploadedFileURL= https://telegram.me/filesbot?start= -chooseFromRecentWeather= Please choose an option from your recent requests: initDirections= Please reply to this message with your starting point. sendDestination= Please reply to this message with your destination. youNeedReplyDirections= I'm sorry, I can't help you unless you reply to the message I sent you. -pleaseSendMeCityWeather= Send me the city and country you are interested in, use this format: CITY,COUNTRY -chooselanguage= Please, choose a language from the list to change to that language. +chooselanguage= Please, select a language from the list to change to that language. errorLanguage= We don't support that language or a typo was made. The process has been cancelled. directionsInit= %s is %s away from %s and it takes %s to arrive there, following these directions:\n\n directionsNotFound= Directions not found between %s and %s. errorFetchingDirections= Error fetching directions info directionsStep= %s during %s (%s) -weatherForcast= The weather for %s will be:\n %s Thank you for using our Weather Bot. -weatherCurrent= The weather for %s is:\n %s Thank you for using our Weather Bot. +languageModified= Your language setting has been updated. + + +helpWeatherMessage= Curious about the weather?\ +\nJust send me these commands and you'll know a lot better\:\ +\n\t\t%s Get the current weather for a location or city\ +\n\t\t%s Get a 3-day forecast for a location or city\ +\n\t\t%s Set current alerts\ +\n\t\t%s Select a forecast-language\ +\n\t\t%s Change your unit preferences +forecast=%sForecast +current=%sCurrent +help=%sHelp +settings=%sSettings +cancel=%sCancel +location=%sLocation +new=%sNew +languages=%sLanguages +alerts=%sAlerts +units=%sUnits +back=%sBack +delete=%sDelete +showList=%sShow list +rateMe=%sRate me +metricSystem=Metric System +imperialSystem= Imperial System +selectLanguage=Your current language is %s. Select a language from the list to change to that language. +languageUpdated=Your language setting has been updated. +errorLanguageNotFound= We don't support that language or a typo was made. Please select one from the list. +selectUnits=Your current unit setting is %s. Select an option from the list to change it. +unitsUpdated=Your unit settings have been updated. +errorUnitsNotFound= We don't support that unit system or a typo was made. Please select one from the list. +onWeatherNewCommand=Please send me the city you are interested in, please use this format: CITY,COUNTRY +onWeatherLocationCommand=Please send me the location you are interested in. +onCurrentCommandFromHistory=Select an option from your recent requests, "new" to send a new city or "location" to send me a location to get current weather. +onCurrentCommandWithoutHistory=Select "new" to send a new city or "location" to send me a location to get current weather. +onForecastCommandFromHistory=Select an option from your recent requests, "new" to send a new city or "location" to send me a location to get 3-day weather forecast. +onForecastCommandWithoutHistory=Select "new" to send a new city or "location" to send me a location to get a 3-day weather forecast. +weatherCurrent= The weather for %s is:\n\n %s +currentWeatherPartMetric=\t- Weather: %s\n\t- Cloudiness: %s\n\t- Temperature: %s ºC\n\n +currentWeatherPartImperial=\t- Weather: %s\n\t- Cloudiness: %s\n\t- Temperature: %s ºF\n\n +weatherForcast= The weather for %s will be:\n\n %s +forecastWeatherPartMetric= %s On %s \n\t- Forecast: %s\n\t- High temperature: %s ºC\n\t- Low temperature: %s ºC\n\n +forecastWeatherPartImperial= %s On %s \n\t- Forecast: %s\n\t- High temperature: %s ºF\n\t- Low temperature: %s ºF\n\n +weatherAlert= The weather for %s will be:\n\n %s +alertWeatherPartMetric=\t- Forecast: %s\n\t- High temperature: %s ºC\n\t- Low temperature: %s ºC\n\n +alertWeatherPartImperial=\t- Forecast: %s\n\t- High temperature: %s ºF\n\t- Low temperature: %s ºF\n\n +chooseOption=Please, select an option from the menu. +backToMainMenu=Process cancelled, back to main menu. +onSettingsCommand=Please, select an option:\ +\n\t\t%s Languages: Select a forecast-language\ +\n\t\t%s Units: Select your preferred units\ +\n\t\t%s Alerts: Set daily alerts\ +\n\t\t%s Back: Return to main menu +alertsMenuMessage=Here you can manage your alerts or add new ones. +chooseNewAlertCity=Which city do you want to set an alert for? Select an option from your recent requests. +newAlertSaved=%s Your alert for %s has been correctly created, you will receive the weather update twice a day. +initialAlertList=You have %d alerts:\n\n%s +partialAlertList=%s%s\n +noAlertList=I couldn't find any alert for you. +alertDeleted=The selected alert has been deleted. cityNotFound= City not found -errorFetchingWeather= We are sorry, there was an error fetching the weather. -currentWeatherPart= |-- Weather: %s\n|-- Cloudiness: %s\n |-- Temperature: %s ºC\n\n -forecastWeatherPart= * On %s \n\t|--Forecast: %s\n\t|--High temperature: %s ºC\n\t|--Low temperature: %s ºC\n\n -languageModified= Your language has been updated. \ No newline at end of file +errorFetchingWeather= We're sorry, there was an error fetching the weather. +rateMeMessage=If you like this bot, please rate it at https://telegram.me/storebot?start=weatherbot \ No newline at end of file diff --git a/src/main/resources/localisation/strings_es.properties b/src/main/resources/localisation/strings_es.properties index a931d3c..dfd90c3 100644 --- a/src/main/resources/localisation/strings_es.properties +++ b/src/main/resources/localisation/strings_es.properties @@ -1,6 +1,5 @@ -helpWeather= ¿Preocupado por el tiempo?\nSimplemente envíame uno de estos comandos y solucionaré to preocupación\n\n|-- %s CIUDAD,PAÍS \: Obtén el pronóstico para 3 días en tu ciudad.\n|-- %s CIUDAD,PAÍS \: Obtén el tiempo actual en tu ciudad.\n\n|-- Envíame una localización y te daré el pronóstico para ese lugar -helpTransifex= Magia con las palabras es lo que se me da bien, quizás te alegre el día.\n\nPara obtener las últimas traducciones de las aplicaciones de Telegram para un idioma\:\n|-- %s CODIGO_DEL_IDIOMA \: Última traducción para iOS.\n|-- %s CODIGO_DEL_IDIOMA \: Última traducción para Android.\n|-- %s CODIGO_DEL_IDIOMA \: Última traducción para Webogram.\n|-- %s CODIGO_DEL_IDIOMA \: Última traducción para Tdesktop.\n|-- %s CODIGO_DEL_IDIOMA \: Última traducción para OSX App.\n|-- %s CODIGO_DEL_IDIOMA \: Última traducción para Windows Phone.\n\n2. Para la última traducción de la versión beta de Android\:\n|-- %s CODIGO_DEL_IDIOMA \: Última traducción para Android beta. -helpFiles= ¿Quieres compartir un archivo con alguien? Has llegado al puerto adecuado.\n\nComparte archivos usando un link personalizado\:\n|-- %s IDDELARCHIVO \: Obtener un archivo por id.\n|-- %s \: Comenzar a compartir un archivo.\n|-- %s \: Elimina uno de tus archivos.\n|-- %s \: Muestra una lista de tus archivos compartidos. +helpTransifex= Magia con las palabras es lo que se me da bien, quizás te alegre el día.\n\nObtén los últimos archivos de localización de Telegram en tu idioma\:\n|-- %s CÓDIGO_IDIOMA \: Obtén el idioma para iOS.\n|-- %s CÓDIGO_IDIOMA \: Obtén el idioma para Android.\n|-- %s CÓDIGO_IDIOMA \: Obtén el idioma para Webogram.\n|-- %s CÓDIGO_IDIOMA \: Obtén el idioma para Tdesktop.\n|-- %s CÓDIGO_IDIOMA \: Obtén el idioma para OS X.\n|-- %s CÓDIGO_IDIOMA \: Obtén el idioma para Windows Phone.\n\n 2. Obtén un archivo de localización actualizado para tu beta de Android\:\n|-- %s CÓDIGO_IDIOMA\: Obtén el idioma para Android beta. +helpFiles= ¿Quieres compartir un archivo con alguien? Has llegado al puerto adecuado. \n\nComparte archivos usando un enlace personalizado\: \n|-- %s \: ID_ARCHIVO \: Obtener un archivo por id. \n|-- %s \: Iniciar la subida de un archivo. \n|-- %s \: Elige y elimina uno de tus archivos.\n|-- %s \: Muestra una lista de tus archivos compartidos. helpDirections= Un viaje por delante es una buena ocasión, ¿pero no sería mejor conociendo el camino?\n\nPara obtener la ruta que debes seguir entre dos lugares\:\n|-- %s \: Comienza a obtener la ruta sendFileToUpload= Por favor, envíame el archivo que quieres compartir. Asegúrate de adjuntarlo como archivo, no como imagen o vídeo. fileUploaded= Perfecto, ya tengo tu archivo. Envía este link a cualquiera que desees que lo tenga y podrá descargarlo\:\n\n @@ -11,21 +10,66 @@ listOfFiles= Esta es la lista actual de tus archivos compartidos\: noFiles= Aún no has compartido ningún archivo. processFinished= El proceso actual ha sido cancelado. uploadedFileURL= https\://telegram.me/filesbot?start\= -chooseFromRecentWeather= Por favor, selecciona una opción de tus últimas peticiones\: initDirections= Por favor, responde a este mensaje con el lugar de salida. sendDestination= Por favor, responde a este mensaje con el lugar de destino. youNeedReplyDirections= Lo siento, no puedo ayudarte a menos que respondas al mensaje que te he enviado. -pleaseSendMeCityWeather= Envíame la ciudad y el país que te interesa, usa este formato\: CIUDAD,PAÍS -chooselanguage= Por favor, elige un idioma de la lista para que nos entendamos mejor. +chooselanguage= Por favor, elige un idioma de la lista para cambiar a ese idioma. errorLanguage= No soportamos ese idioma o ha habido un error. El proceso ha sido cancelado. directionsInit= %s está a %s de %s y se necesita %s para llegar, siguiendo estas direcciones\:\n\n directionsNotFound= No hemos encontrado una ruta desde %s hasta %s. errorFetchingDirections= Ha habido un error obteniendo la ruta directionsStep= %s durante %s (%s) -weatherForcast= El tiempo para %s será\:\n%s Gracias por usar nuestro Bot del tiempo. -weatherCurrent= El tiempo para %s es\:\n%s Gracias por usar nuestro Bot del tiempo. +languageModified= Tus ajustes de idioma fueron actualizados. + + +helpWeatherMessage= ¿Te interesa el estado del tiempo?\nEnvíame estos comandos y te mantendré informado\:\n\t\t%s Obtén el tiempo actual \n\t\t%s Obtén el pronóstico para 3 días \n\t\t%s Establece alertas\n\t\t%s Elige un idioma\n\t\t%s Cambia las unidades +forecast=%sPronóstico +current=%sTiempo actual +help=%sAyuda +settings=%sAjustes +cancel=%sCancelar +location=%sUbicación +new=%sNueva +languages=%sIdiomas +alerts=%sAlertas +units=%sUnidades +back=%sAtrás +delete=%sEliminar +showList=%sMostrar lista +rateMe=%sPuntúame +metricSystem=Sistema métrico +imperialSystem= Sistema imperial +selectLanguage=Tu idioma actual es %s. Elige un idioma de la lista para usarlo. +languageUpdated=Tus ajustes de idioma fueron actualizados. +errorLanguageNotFound= No soportamos ese idioma o se cometió un error ortográfico. Por favor elige uno de la lista. +selectUnits=Tu sistema de unidades actual es %s. Elige una opción de la lista para cambiarlo. +unitsUpdated=Tus ajustes de unidades fueron actualizados. +errorUnitsNotFound= No soportamos ese sistema de unidades o se cometió un error ortográfico. Por favor elige uno de la lista. +onWeatherNewCommand=Por favor, envíame la ciudad en la que estas interesado, usa este formato\: CIUDAD,PAÍS +onWeatherLocationCommand=Por favor, envíame la ubicación en la que estás interesado. +onCurrentCommandFromHistory=Elige una opción de tu solicitudes recientes, "nueva" para enviar una nueva ciudad o "ubicación" para enviarme una ubicación para obtener el tiempo actual. +onCurrentCommandWithoutHistory=Elige "nueva" para enviar una nueva ciudad o "ubicación" para enviarme una ubicación para obtener el tiempo actual. +onForecastCommandFromHistory=Elige una opción de tus solicitudes recientes, "nueva" para enviar una ciudad o "ubicación" +onForecastCommandWithoutHistory=Elige "nueva" para enviar una nueva ciudad o "ubicación" +weatherCurrent= El tiempo para %s es\:\n\n%s +currentWeatherPartMetric=\t- Tiempo\: %s\n\t- Nubes\: %s\n\t-Temperatura\: %s ºC +currentWeatherPartImperial=\t- Tiempo\: %s\n\t- Nubes\: %s\n\t-Temperatura\: %s ºF +weatherForcast= El tiempo para %s será\:\n\n%s +forecastWeatherPartMetric= %s el %s\n- Pronóstico\: %s\n\t- Temperatura máxima\: %s ºC\n\t- Temperatura mínima\: %s ºC\n +forecastWeatherPartImperial= %s el %s\n- Pronóstico\: %s\n\t- Temperatura máxima\: %s ºF\n\t- Temperatura mínima\: %s ºF\n +weatherAlert= El tiempo para %s será\:\n\n%s +alertWeatherPartMetric=\t- Pronóstico\: %s\n\t- Temperatura máxima\: %s ºC\n\t- Temperatura mínima\: %s ºC\n +alertWeatherPartImperial=\t- Pronóstico\: %s\n\t- Temperatura máxima\: %s ºF\n\t- Temperatura mínima\: %s ºF\n +chooseOption=Por favor, elige una opción del menú. +backToMainMenu=Proceso cancelado, vuelta al menú principal. +onSettingsCommand=Por favor, elige una opción\:\n\t\t%s Idiomas\: elige un idioma\n\t\t%s Unidades\: cambia las unidades\n\t\t%s Alertas\: establece alertas diarias\n\t\t%s Atrás\: vuelve al menú principal +alertsMenuMessage=Aquí puedes administrar tus alertas o añadir nuevas. +chooseNewAlertCity=¿Para qué ciudad quieres establecer una alerta? Elige una opción de tus solicitudes recientes. +newAlertSaved=%s Tu alerta para %s fue añadida correctamente, recibirás actualizaciones del tiempo dos veces al día. +initialAlertList=Tienes %d alertas\:\n\n%s +partialAlertList=%s%s\n +noAlertList=No pude encontrar ninguna alerta. +alertDeleted=La alerta seleccionada fue eliminada. cityNotFound= Ciudad no encontrada -errorFetchingWeather= Lo siento, ha habido un error obteniendo el tiempo. -currentWeatherPart= |-- Tiempo\: %s\n|-- Nubes\: %s\n|-- Temperatura\: %s ºC\n -forecastWeatherPart= * El %s \n\t|--Pronóstico\: %s\n\t|--Temperatura máxima\: %s ºC\n\t|--Temperatura mínima\: %s ºC\n\n -languageModified= Tu idioma ha sido modificado. \ No newline at end of file +errorFetchingWeather= Lo sentimos, hubo un error solicitando el tiempo. +rateMeMessage=Si te gusta este bot, por favor, puntúalo en https\://telegram.me/storebot?start\=weatherbot diff --git a/src/main/resources/localisation/strings_nl.properties b/src/main/resources/localisation/strings_nl.properties new file mode 100644 index 0000000..c7e517b --- /dev/null +++ b/src/main/resources/localisation/strings_nl.properties @@ -0,0 +1,75 @@ +helpTransifex= Schieten woorden tekort of heb je last van een babylonische dwaling? Probeer mij dan eens uit voor een Telegram-vertaling.\n\nOm de laatste vertaling voor Telegram te verkrijgen voor een taal\:\n|-- %s TAAL_CODE \: De meest recente iOS-vertaling.\n|-- %s TAAL_CODE \: De meest recente Android-vertaling\n|-- %s TAAL_CODE \: De meest recente Webogram-vertaling.\n|-- %s TAAL_CODE \: De meest recente Tdesktop-vertaling.\n|-- %s TAAL_CODE \: De meest recente OSX-vertaling.\n|-- %s TAAL_CODE \: De meest recente Windows Phone-vertaling.\n\n2. Alleen voor Android beta in je huidige taal\:\n|-- %s TAAL_CODE \: De meest Android-beta vertaling\n\n(TAAL_CODE voorbeeld\: nl) +helpFiles= Het downloadverbod is van kracht want Brein greep de macht, je downloads zijn nu officieel illegaal, maar een bestandje met mij delen, zodat anderen het kunnen vinden, is dat eigenlijk wel zo abnormaal?\n\nBestanden delen via een link\:\n|-- %s BESTANDSID \: Ontvang een bestand met ID.\n|-- %s \: Begin een bestandsupload.\n|-- %s \: Kies een bestand om te verwijderen.\n|-- %s \: Geef een lijst met gedeelde bestanden weer. +helpDirections= Vele wegen leiden naar Rome, maar terug naar Leiden is toch nog een hele klus, bent u het zoeken op de kaart al zat? Vraag het aan mij en ik breng u op het rechte pad\!\n\nOm een routebeschrijving tussen twee locaties te ontvangen\:\n|-- %s \: Start een routebeschrijving. +sendFileToUpload= Stuur mij het bestand dat je wilt delen. Zorg ervoor dat je het stuurt als een bestand en niet als een afbeelding of video. +fileUploaded= Je bestand is geüpload. Stuur deze link naar iedereen die je maar wilt en zij kunnen het bestand ermee downloaden\:\n\n +deleteUploadedFile= Selecteer het bestand dat je wilt verwijderen\: +fileDeleted= Het bestand is verwijderd. +wrongFileId= Sorry, ik kan het bestand met dat ID niet vinden. Mogelijk is er een typefout gemaakt of is het bestand al verwijderd. +listOfFiles= Dit zijn je gedeelde bestanden op het moment\: +noFiles= Je hebt nog geen bestanden gedeeld. +processFinished= Het huidige proces is geannuleerd. +uploadedFileURL= https\://telegram.me/filesbot?start\= +initDirections= Beantwoord dit bericht met je vertrekpunt. +sendDestination= Beantwoord dit bericht met je bestemming. +youNeedReplyDirections= Het spijt me, ik kan je niet helpen tenzij je het bericht dat ik stuurde beantwoord. +chooselanguage= Kies een taal uit de lijst om de taal te wijzigen. +errorLanguage= Deze taal ondersteunen we niet of je hebt een typefout gemaakt. Het proces is geannuleerd. +directionsInit= %s is %s verwijderd van %s en het duurt %s om er te komen met de volgende routebeschrijving\:\n\n +directionsNotFound= Routebeschrijving tussen %s en %s niet gevonden. +errorFetchingDirections= Ophalen van routebeschrijving mislukt +directionsStep= %s voor %s (%s) +languageModified= Je taalinstelling is bijgewerkt. + + +helpWeatherMessage= Zon of regen, hagel of ijs?\nVraag het aan mij en ik maak u weer wijs\!\n\n\t\t%s Om de huidige weersvoorspelling te ontvangen\n\t\t%s Voor een drie-daagse weersvoorspelling\n\t\t%s Waarschuwingen instellen\n\t\t%s Kies een weersvoorspellingstaal\n\t\t%s Kies een eenhedenstelsel +forecast=%sVoorspelling +current=%sHuidig +help=%sHelp +settings=%sInstellingen +cancel=%sAnnuleren +location=%sLocatie +new=%sNieuw +languages=%sTalen +alerts=%sWaarschuwingen +units=%sEenheden +back=%sTerug +delete=%sVerwijderen +showList=%sLijst weergeven +rateMe=%sBeoordeel mij +metricSystem=Metriek stelsel +imperialSystem= Imperiaal stelsel +selectLanguage=Je huidige taal is %s. Kies een taal van de lijst om deze instelling te wijzigen. +languageUpdated=Je taalinstelling is bijgewerkt. +errorLanguageNotFound= Deze taal ondersteunen we niet of je hebt een typefout gemaakt. Kies een taal uit de lijst. +selectUnits=Je huidige eenhedenstelsel is %s. Kies een optie van de lijst om deze instelling te wijzigen. +unitsUpdated=Je gekozen eenheid is bijgewerkt. +errorUnitsNotFound= Dit stelsel ondersteunen we helaas niet, of je hebt een typefout gemaakt. Kies een stelsel van de lijst. +onWeatherNewCommand=Stuur me de stad waarin je geïnteresseerd bent. Gebruik dit formaat\: STAD,LAND +onWeatherLocationCommand=Stuur me de locatie waarin je geïnteresseerd bent. +onCurrentCommandFromHistory=Kies een optie van je recente verzoeken, "nieuw" om een stad te sturen of "locatie" om mij een locatie te sturen en de huidige weersvoorspelling te ontvangen. +onCurrentCommandWithoutHistory=Kies "nieuw" om een stad te sturen of "locatie" om mij een locatie te sturen de huidige weersvoorspelling te ontvangen. +onForecastCommandFromHistory=Kies een optie van je recente verzoeken, "nieuw" om een stad te sturen of "locatie" om mij een locatie te sturen en een drie-daagse weersvoorspelling te ontvangen. +onForecastCommandWithoutHistory=Kies "nieuw" om een stad te sturen of "locatie" om mij een locatie te sturen en een drie-daagse weersvoorspelling te ontvangen. +weatherCurrent= De weersverwachting voor %s is\:\n\n%s +currentWeatherPartMetric=\t- Weer\: %s\n\t- Bewolking\: %s\n\t- Temperatuur\: %s ºC\n +currentWeatherPartImperial=\t- Weer\: %s\n\t- Bewolking\: %s\n\t- Temperatuur\: %s ºF\n +weatherForcast= De weersverwachting voor %s\:\n\n%s +forecastWeatherPartMetric= %s op %s \n\t- Voorspelling\: %s\n\t- Hoogste temperatuur\: %s ºC\n\t- Laagste temperatuur\: %s ºC\n +forecastWeatherPartImperial= %s on %s \n\t- Voorspelling\: %s\n\t- Hoogste temperatuur\: %s ºF\n\t- Laagste temperatuur\: %s ºF\n +weatherAlert= De weersverwachting voor %s\:\n\n%s +alertWeatherPartMetric=\t- Voorspelling\: %s\n\t- Hoogste temperatuur\: %s ºC\n\t- Laagste temperatuur\: %s ºC\n +alertWeatherPartImperial=\t- Voorspelling\: %s\n\t- Hoogste temperatuur\: %s ºF\n\t- Laagste temperatuur\: %s ºF\n +chooseOption=Selecteer een optie uit het menu. +backToMainMenu=Proces geannuleerd, terug naar het hoofdmenu. +onSettingsCommand=Maak een keuze\:\n\t\t%s Taal\: Kies een weersvoorspellings-taal\n\t\t%s Eenheid\: Wijzig je voorkeurseenheid.\n\t\t%s Alerts\: dagelijkse waarschuwingen instellen\n\t\t%s Back\: Terug naar het hoofdmenu +alertsMenuMessage=Hier kan je je waarschuwingen beheren of nieuwe toevoegen. +chooseNewAlertCity=Voor welke stad wil je een waarschuwing instellen? Kies een optie van je recente verzoeken. +newAlertSaved=%s Je waarschuwing voor %s is aangemaakt, je ontvangt twee keer per dag een weersvoorspelling. +initialAlertList=Je hebt %d waarschuwingen\:\n\n%s +partialAlertList=%s%s\n +noAlertList=Geen waarschuwingen gevonden. +alertDeleted=De geselecteerde waarschuwing is verwijderd. +cityNotFound= Stad niet gevonden. +errorFetchingWeather= Sorry, er is iets misgegaan bij het ophalen van het weer. +rateMeMessage=Als je deze bot leuk vindt dan kan je hem hier beoordelen https\://telegram.me/storebot?start\=weatherbot diff --git a/src/main/resources/localisation/strings_pt.properties b/src/main/resources/localisation/strings_pt.properties index 2f92d9a..09efd99 100644 --- a/src/main/resources/localisation/strings_pt.properties +++ b/src/main/resources/localisation/strings_pt.properties @@ -1,5 +1,4 @@ -helpWeather= Curioso sobre o clima?\nBasta me enviar esses comandos e você saberá muito mais.\n\n|-- %s CIDADE,PAÍS \: Obter a previsão do tempo dos próximos 3 dias para uma cidade.\n|-- %s CIDADE,PAÍS \: Obter o clima atual da cidade.\n\n|-- Ou envie a localização para obter a previsão. -helpTransifex= Magia com palavras é o que eu faço, espero alegrar seu dia.\n\nPara obter a última tradução para os aplicativos do Telegram em um idioma\:\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para iOS.\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para Android.\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para Webogram.\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para TDesktop.\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para OSX.\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para Windows Phone.\n\n2. Para obter a o arquivo de tradução atualizado para o seu aplicativo beta do Android\:\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para Android-beta. +helpTransifex= Para obter a última tradução para os aplicativos do Telegram em um idioma\:\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para iOS.\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para Android.\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para Webogram.\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para TDesktop.\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para OSX.\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para Windows Phone.\n\n2. Para obter a o arquivo de tradução atualizado para o seu aplicativo beta do Android\:\n|-- %s CODIGO_DO_IDIOMA\: Obter a última tradução para Android-beta. helpFiles= Deseja compartilhar um arquivo com outras pessoas? Você está no lugar certo\!\n\nCompartilhe arquivos através de um link\:\n|-- %s IDDOARQUIVO \: Obter arquivo pelo id.\n|-- %s \: Iniciar seu upload de arquivo.\n|-- %s \: Escolher um de seus arquivos para apagar.\n|-- %s \: Mostrar lista de seus arquivos compartilhados. helpDirections= A estrada à frente, cheia de boas intenções, o caminho logo à frente no entanto, é o que eu tendo a mencionar.\n\nPara obter localizações entre dois locais\:\n|-- %s \: Começar para receber as direções sendFileToUpload= Por favor, envie-me o arquivo que deseja compartilhar. Certifique-se de anexá-lo como arquivo, e não como uma imagem ou vídeo. @@ -11,21 +10,66 @@ listOfFiles= Essa é sua lista de arquivos compartilhados atualmente\: noFiles= Você não compartilhou arquivos ainda. processFinished= O processo atual foi cancelado. uploadedFileURL= https\://telegram.me/filesbot?start\= -chooseFromRecentWeather= Por favor, escolha uma opção de suas solicitações recentes\: initDirections= Por favor, responda a essa mensagem com seu ponto de partida. sendDestination= Por favor, responda a essa mensagem com seu destino. youNeedReplyDirections= Me desculpe, não consigo ajudá-lo a menos que você responda a mensagem que lhe enviei. -pleaseSendMeCityWeather= Envie-me a cidade e país que você está interessado, use o formato\: CIDADE,PAÍS -chooselanguage= Por favor, escolha um idioma da lista para alterar a linguagem do bot. +chooselanguage= Por favor, escolha um idioma da lista para alterar para essa linguagem; errorLanguage= Nós não temos suporte para essa linguagem ou ela foi escrita errada. Esse processo foi cancelado. directionsInit= %s é %s distante de %s e demora %s para chegar lá, seguindo essas direções\:\n\n directionsNotFound= Direções não encontradas entre %s e %s errorFetchingDirections= Erro ao obter informações de direção. directionsStep= %s durante %s (%s) -weatherForcast= O clima para %s será de\:\n%s Obrigado por usar o Weather Bot -weatherCurrent= O clima para %s é de\:\n%s Obrigado por usar o Weather Bot +languageModified= Sua configuração de idioma foi atualizada. + + +helpWeatherMessage= Curioso sobre o clima?\nBasta me enviar esses comandos e você saberá muito mais.\n\n\t\t%s Obter o clima atual de uma localização ou cidade\n\t\t%s Obter a previsão de 3 dias de uma localização ou cidade\n\t\t%s Definir alertas atuais\n\t\t%s Selecionar um idioma para a previsão\n\t\t%s Alterar suas preferências de unidade +forecast=%sPrevisão +current=%sAtual +help=%sAjuda +settings=%sConfiguração +cancel=%sCancelar +location=%sLocalização +new=%sNovo +languages=%sIdiomas +alerts=%sAlertas +units=%sUnidades +back=%sVoltar +delete=%sApagar +showList=%sMostrar lista +rateMe=%sMe avalie +metricSystem=Sistema Métrico +imperialSystem= Sistema Imperial +selectLanguage=Seu idioma atual é %s. Selecione um idioma da lista para alterar para essa linguagem. +languageUpdated=Sua configuração de idioma foi atualizada. +errorLanguageNotFound= Nós não temos suporte para essa linguagem ou ela foi escrita errada. Por favor, selecione um idioma da lista. +selectUnits=Sua unidade atual é %s. Selecione uma opção da lista para alterar. +unitsUpdated=Sua configuração de unidade foi atualizada. +errorUnitsNotFound= Nós não temos suporte para essa unidade ou ela foi escrita errada. Por favor, selecione um tipo de unidade da lista. +onWeatherNewCommand=Envie-me a cidade e país que você está interessado, use o formato\: CIDADE,PAÍS +onWeatherLocationCommand=Por favor, selecione a localização que você está interessado. +onCurrentCommandFromHistory=Selecione uma opção de suas solicitações recentes, "novo" para enviar uma nova cidade ou "localização" para me enviar seu local e obter o clima atual. +onCurrentCommandWithoutHistory=Selecione "novo" para enviar uma nova cidade ou "localização" para me enviar a localização e obter o clima atual. +onForecastCommandFromHistory=Selecione uma opção de suas solicitações recentes, "novo" para enviar uma nova cidade ou "localização" para me enviar seu local e obter a previsão de 3 dias. +onForecastCommandWithoutHistory=Selecione "novo" para enviar uma nova cidade ou "localização" para me enviar seu local e obter a previsão de 3 dias. +weatherCurrent= O clima para %s é de\:\n\n%s +currentWeatherPartMetric=\t- Clima\: %s\n\t- Nebulosidade\: %s\n\t- Clima\: %s ºC\n\n +currentWeatherPartImperial=\t- Clima\: %s\n\t- Nebulosidade\: %s\n\t- Temperatura\: %s ºF\n\n +weatherForcast= O clima para %s será de\:\n\n%s +forecastWeatherPartMetric= %s Em %s \n\t- Previsão\: %s\n\t- Máxima\: %s ºC\n\t- Mínima\: %s ºC\n\n +forecastWeatherPartImperial= %s Em %s \n\t- Previsão\: %s\n\t- Máxima\: %s ºF\n\t- Mínima\: %s ºF\n\n +weatherAlert= O clima para %s será de\:\n\n%s +alertWeatherPartMetric=\t- Previsão\: %s\n\t- Máxima\: %s ºC\n\t- Mínima\: %s ºC\n\n +alertWeatherPartImperial=\t- Previsão\: %s\n\t- Máxima\: %s ºF\n\t- Mínima\: %s ºF\n\n +chooseOption=Por favor, selecione uma opção do menu. +backToMainMenu=Processo cancelado, de volta ao menu principal. +onSettingsCommand=Por favor, selecione uma opção\:\n\t\t%s Idiomas\: Selecione um idioma para a previsão\n\t\t%s Unidades\: Selecione sua unidade preferida\n\t\t%s Alertas\: Definir alertas diários\n\t\t%s Voltar\: Voltar ao menu principal +alertsMenuMessage=Aqui você pode alterar ou adicionar novos alertas. +chooseNewAlertCity=Para qual cidade você deseja definir um alerta? Selecione uma opção de suas solicitações recentes. +newAlertSaved=%s Seu alerta para %s foi criado corretamente, você irá receber atualizações sobre o clima duas vezes ao dia. +initialAlertList=Você tem %d alertas\:\n\n%s +partialAlertList=%s%s\n +noAlertList=Eu não consegui encontrar nenhum alerta para você. +alertDeleted=O alerta selecionado foi apagado. cityNotFound= Cidade não encontrada -errorFetchingWeather= Desculpe, houve um erro ao obter as informações sobre o clima. -currentWeatherPart= |-- Clima\: %s\n|-- Nebulosidade\: %s\n|-- Temperatura\: %s ºC\n\n -forecastWeatherPart= * Em %s\n\t|--Clima\: %s\n\t|--Máxima\: %s ºC\n\t|--Mínima\: %s ºC\n\n -languageModified= Seu idioma foi atualizado. \ No newline at end of file +errorFetchingWeather= Desculpe, houve um erro ao obter o clima. +rateMeMessage=Se você gosta deste bot, por favor nos avalie em https\://telegram.me/storebot?start\=weatherbot