diff --git a/.idea/misc.xml b/.idea/misc.xml
index 9afc2ea..1577011 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -58,7 +58,7 @@
-
+
\ No newline at end of file
diff --git a/src/elements/Chat.java b/src/elements/Chat.java
new file mode 100644
index 0000000..2cc2636
--- /dev/null
+++ b/src/elements/Chat.java
@@ -0,0 +1,123 @@
+package elements;
+
+import elements.exceptions.UserNotExistingException;
+
+import java.time.LocalDate;
+import java.util.*;
+
+/**
+ * Created by vylion on 4/21/16.
+ */
+public class Chat {
+ private static final String DATE_TAG = "Date=";
+
+ private Map users;
+ private LocalDate lastPole;
+
+ public Chat() {
+ users = new HashMap();
+ lastPole = null;
+ }
+
+ public boolean exists(String user) {
+ return users.containsKey(user);
+ }
+
+ public void add(String user) {
+ users.put(user, 0);
+ }
+
+ public void add(String user, int p) {
+ users.put(user, p);
+ }
+
+ public void winPole(String user) {
+ if(!users.containsKey(user)) add(user);
+ users.replace(user, users.get(user)+1);
+ lastPole = LocalDate.now();
+ }
+
+ public boolean availablePole() {
+ LocalDate today = LocalDate.now();
+
+ return (lastPole == null || today.isAfter(lastPole));
+ }
+
+ public String getRanking() {
+ List> top;
+ String ranking = "";
+ Map.Entry[] ts = new Map.Entry[users.size()];
+
+ top = Arrays.asList((users.entrySet().toArray(ts)));
+ top.sort(new UserComparator());
+
+ for(int i = 0; i < top.size(); i++) {
+ ranking += "[" + (i+1) + ".] @" + getUsername(top.get(i)) + ": ";
+ ranking += getPoles(top.get(i)) + "\n";
+ }
+
+ return ranking;
+ }
+
+ public String toTxt() {
+ String s = DATE_TAG;
+ if(lastPole == null) s += "null\n";
+ else s += lastPole + "\n";
+ Iterator it = users.entrySet().iterator();
+
+ while(it.hasNext()) {
+ Map.Entry entry = (Map.Entry) it.next();
+ s += getUsername(entry) + ":" + getPoles(entry) + "\n";
+ }
+
+ return s;
+ }
+
+ public static Chat fromTxt(List lines) {
+ Chat c = new Chat();
+
+ if(lines.get(0).startsWith(DATE_TAG)) {
+ String pole = lines.get(0).substring(DATE_TAG.length());
+ String[] reading = pole.split("-");
+ LocalDate poleDate = LocalDate.of(Integer.parseInt(reading[0]),
+ Integer.parseInt(reading[1]), Integer.parseInt(reading[2]));
+ c.setPole(poleDate);
+
+ for(int i = 1; i < lines.size(); i++) {
+ reading = lines.get(i).split(":");
+ c.add(reading[0],Integer.parseInt(reading[1]));
+ }
+ }
+
+ else {
+ for(int i = 0; i < lines.size(); i++) {
+ String[] reading = lines.get(i).split(":");
+ c.add(reading[0],Integer.parseInt(reading[1]));
+ }
+ }
+
+
+ return c;
+ }
+
+ private void setPole(LocalDate d) {
+ lastPole = d;
+ }
+
+ private String getUsername(Map.Entry e) {
+ return e.getKey();
+ }
+
+ private int getPoles(Map.Entry e) {
+ return e.getValue();
+ }
+}
+
+class UserComparator implements Comparator {
+
+ @Override
+ public int compare(Map.Entry entr1, Map.Entry entr2) {
+
+ return ((Integer) entr2.getValue()).compareTo((Integer) entr1.getValue());
+ }
+}
diff --git a/src/elements/Persistence.java b/src/elements/Persistence.java
new file mode 100644
index 0000000..b6b318f
--- /dev/null
+++ b/src/elements/Persistence.java
@@ -0,0 +1,76 @@
+package elements;
+
+import elements.exceptions.ReadErrorException;
+import elements.exceptions.SaveErrorException;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created by vylion on 4/14/16.
+ */
+public class Persistence {
+ private static Persistence persistence;
+
+ private Persistence() {
+
+ }
+
+ public static Persistence getInstance() {
+ if(persistence == null) persistence = new Persistence();
+ return persistence;
+ }
+
+ public void saveChat(long chat_id, Chat c) throws SaveErrorException {
+ try {
+ List lines = Arrays.asList(c.toTxt().split("\n"));
+
+ Path file = Paths.get("chats/" + chat_id + ".txt");
+ if (!Files.exists(file.getParent()))
+ Files.createDirectories(file.getParent());
+ Files.write(file, lines, Charset.forName("UTF-8"));
+ } catch (IOException e) {
+ throw new SaveErrorException(chat_id);
+ }
+
+ return;
+ }
+
+ public HashMap readChats() throws ReadErrorException {
+ HashMap chats = new HashMap();
+
+ if(!Files.exists(Paths.get("chats/"))) return chats;
+
+ try {
+ String filename;
+ Chat chat;
+ List files = Files.walk(Paths.get("chats/"), 1).collect(Collectors.toList());
+ Path file;
+ List lines;
+
+ for(int i = 0; i < files.size(); i++) {
+ file = files.get(i);
+ filename = file.getFileName().toString();
+ if(filename.endsWith(".txt")) {
+ filename = filename.substring(0,filename.length() - 4);
+ System.out.println("Reading " + filename);
+
+ lines = Files.readAllLines(file);
+ chats.put(Long.parseLong(filename), Chat.fromTxt(lines));
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new ReadErrorException();
+ }
+
+ return chats;
+ }
+}
diff --git a/src/elements/exceptions/PoleBlockedException.java b/src/elements/exceptions/PoleBlockedException.java
new file mode 100644
index 0000000..db889ec
--- /dev/null
+++ b/src/elements/exceptions/PoleBlockedException.java
@@ -0,0 +1,11 @@
+package elements.exceptions;
+
+/**
+ * Created by vylion on 4/21/16.
+ */
+public class PoleBlockedException extends Exception {
+
+ public PoleBlockedException() {
+ super("La pole de hoy ya ha sido conseguida. Vuélvelo a intentar mañana.");
+ }
+}
diff --git a/src/elements/exceptions/ReadErrorException.java b/src/elements/exceptions/ReadErrorException.java
new file mode 100644
index 0000000..7142929
--- /dev/null
+++ b/src/elements/exceptions/ReadErrorException.java
@@ -0,0 +1,26 @@
+package elements.exceptions;
+
+import java.io.IOException;
+
+/**
+ * Created by vylion on 4/15/16.
+ */
+public class ReadErrorException extends IOException {
+ public ReadErrorException() {
+ super("Ha ocurrido un error al leer los datos. " +
+ "Contacta con mi creador o algo. io k se xdxd");
+ }
+ public ReadErrorException(long chat_id) {
+ super("Ha ocurrido un error al leer los datos del chat " + chat_id +
+ ". Contacta con mi creador o algo. io k se xdxd");
+ }
+
+ @Override
+ public String getLocalizedMessage() {
+ return "Couldn't read file. You're on your own on this one.";
+ }
+
+ public String getLocalizedMessage(long chat_id) {
+ return "Couldn't read file " + chat_id + ". You're on your own on this one.";
+ }
+}
diff --git a/src/elements/exceptions/SaveErrorException.java b/src/elements/exceptions/SaveErrorException.java
new file mode 100644
index 0000000..c2a3ee7
--- /dev/null
+++ b/src/elements/exceptions/SaveErrorException.java
@@ -0,0 +1,26 @@
+package elements.exceptions;
+
+import java.io.IOException;
+
+/**
+ * Created by vylion on 4/15/16.
+ */
+public class SaveErrorException extends IOException {
+ public SaveErrorException() {
+ super("Ha ocurrido un error al guardar los datos. Contacta con mi creador o algo. io k se xdxd");
+ }
+
+ public SaveErrorException(long chat_id) {
+ super("Ha ocurrido un error al guardar los datos del chat " + chat_id +
+ ". Contacta con mi creador o algo. io k se xdxd");
+ }
+
+ @Override
+ public String getLocalizedMessage() {
+ return "Couldn't save to file. You're on your own on this one.";
+ }
+
+ public String getLocalizedMessage(long chat_id) {
+ return "Couldn't save " + chat_id + " to file. You're on your own on this one.";
+ }
+}
diff --git a/src/elements/exceptions/UserNotExistingException.java b/src/elements/exceptions/UserNotExistingException.java
new file mode 100644
index 0000000..8e9d05e
--- /dev/null
+++ b/src/elements/exceptions/UserNotExistingException.java
@@ -0,0 +1,11 @@
+package elements.exceptions;
+
+/**
+ * Created by vylion on 4/21/16.
+ */
+public class UserNotExistingException extends Exception {
+
+ public UserNotExistingException() {
+ super("No tengo constancia de ninguna persona con ese nombre de usuario.");
+ }
+}
diff --git a/src/main/Main.java b/src/main/Main.java
index 1b20fda..0714418 100644
--- a/src/main/Main.java
+++ b/src/main/Main.java
@@ -1,6 +1,7 @@
package main;
import com.mashape.unirest.http.exceptions.UnirestException;
+import elements.exceptions.ReadErrorException;
/**
* Created by vylion on 4/1/16.
@@ -16,6 +17,9 @@ public class Main {
} catch (UnirestException e) {
System.out.println("Unirest Error catched.");
e.printStackTrace();
+ } catch (ReadErrorException e) {
+ System.out.println(e.getMessage());
+ e.printStackTrace();
}
}
}
diff --git a/src/main/Vylbot.java b/src/main/Vylbot.java
index a61b8cf..685ab39 100644
--- a/src/main/Vylbot.java
+++ b/src/main/Vylbot.java
@@ -4,6 +4,11 @@ import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
+import elements.Chat;
+import elements.Persistence;
+import elements.exceptions.PoleBlockedException;
+import elements.exceptions.ReadErrorException;
+import elements.exceptions.SaveErrorException;
import org.json.JSONArray;
import org.json.JSONObject;
@@ -23,8 +28,9 @@ public class Vylbot {
private static final int COMMAND_COUNT_START = 0;
private static final int COMMAND_START = COMMAND_COUNT_START;
private static final int COMMAND_HELP = COMMAND_START + 1;
- private static final int COMMAND_POLE = COMMAND_HELP + 1;
- private static final int COMMAND_COUNT_END = COMMAND_POLE + 1;
+ private static final int COMMAND_RANKING = COMMAND_HELP + 1;
+ private static final int COMMAND_TALIBOT_STATS = COMMAND_RANKING + 1;
+ private static final int COMMAND_COUNT_END = COMMAND_TALIBOT_STATS + 1;
private static final int WARNING_COUNT_START = COMMAND_COUNT_END;
private static final int WARNING_UNKNOWN_ERROR = WARNING_COUNT_START;
@@ -34,13 +40,17 @@ public class Vylbot {
private static final int WARNING_NO_GROUP = WARNING_NOT_IMPLEMENTED + 1;
private static final int WARNING_COUNT_END = WARNING_NO_GROUP + 1;
- private ArrayList commands;
+ private List commands;
+ private Map chats;
- public Vylbot() {
+ public Vylbot() throws ReadErrorException {
+ chats = Persistence.getInstance().readChats();
+ commands = new ArrayList<>();
commands.add(COMMAND_START, "/start");
commands.add(COMMAND_HELP, "/help");
- commands.add(COMMAND_POLE, "/pole");
+ commands.add(COMMAND_RANKING, "/ranking");
+ commands.add(COMMAND_TALIBOT_STATS, "!pole stats");
}
public String getUsername() {
@@ -181,10 +191,9 @@ public class Vylbot {
if (message.has("text")) {
String text = message.getString("text");
- if (text.startsWith("/")) {
- if (user == null) sendMessage(chat_id, getInformation(WARNING_NO_USERNAME));
- else handleInput(chat_id, chatType.contains("group"), user, text);
- }
+ if (text.startsWith("/") || text.startsWith("!")) handleInput(chat_id, chatType.contains("group"), user, text);
+ else handleText(chat_id, chatType.contains("group"), user, text);
+
return;
}
}
@@ -216,11 +225,11 @@ public class Vylbot {
sendMessage(chat_id, getInformation(COMMAND_HELP), PARSE_MARKDOWN);
return;
- case COMMAND_POLE:
- sendMessage(chat_id, getInformation(WARNING_NOT_IMPLEMENTED));
+ case COMMAND_TALIBOT_STATS:
+ case COMMAND_RANKING:
+ sendMessage(chat_id, chats.get(chat_id).getRanking());
return;
-
default: return;
}
}
@@ -236,26 +245,49 @@ public class Vylbot {
return;
default:
- sendMessage(chat_id, getInformation(WARNING_NO_GROUP));
return;
}
}
-
- /*private boolean exists(long chat_id, String user) {
- return chats.containsKey(chat_id) && chats.get(chat_id).exists(user);
- }*/
-
- private String getPole(long chat_id, String user) {
-
- return "Congratulations " + user + ", you got the daily pole position! " +
- "You win 200 pepes. Try again in 24 hours.";
+ private void handleText(long chat_id, boolean group, String user, String text) throws UnirestException {
+ if(text.toLowerCase().contains("pole")) {
+ if(group) {
+ if (user == null) sendMessage(chat_id, getInformation(WARNING_NO_USERNAME));
+ else try {
+ sendMessage(chat_id, winPole(chat_id, user));
+ } catch (PoleBlockedException e) {
+ return;
+ }
+ }
+ else sendMessage(chat_id, getInformation(WARNING_NO_GROUP));
+ }
}
- /*private void saveChat(long chat_id) throws SaveErrorException {
- Persistence.getInstance().saveChat(chat_id, chats.get(chat_id));
- chats.get(chat_id).setDirty(false);
- }*/
+ private boolean exists(long chat_id, String user) {
+ return chats.containsKey(chat_id) && chats.get(chat_id).exists(user);
+ }
+
+ private String winPole(long chat_id, String user) throws PoleBlockedException {
+ if(!chats.containsKey(chat_id)) chats.put(chat_id, new Chat());
+ if(!chats.get(chat_id).availablePole()) throw new PoleBlockedException();
+
+ try {
+ chats.get(chat_id).winPole(user);
+ saveChat(chat_id);
+ return "El usuario @" + user + " ha hecho la pole!";
+ } catch (SaveErrorException e) {
+ return e.getMessage();
+ }
+ }
+
+ private void saveChat(long chat_id) throws SaveErrorException {
+ try {
+ Persistence.getInstance().saveChat(chat_id, chats.get(chat_id));
+ } catch (SaveErrorException e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
private String getInformation(int command) {
switch (command) {
@@ -263,28 +295,12 @@ public class Vylbot {
return "Hola. Soy el bot personal de Vylion.";
case COMMAND_HELP:
- return "Here is a list of the commands I accept:\n\n" +
- "/register - Open a new vault in this chat under your name\n" +
- "/newbet - Start the creation of a new bet. _*This will lock the " +
- "bot in a bet creation until finished*_\n" +
- "/done - While on a bet creation, it finishes it and asks you to " +
- "designate the bet moderator. _*Only the bet creator can use " +
- "this*_\n" +
- "/checkbet - Shows the current state of the bet.\n" +
- "/closebet - If there's a current active bet, it finishes it " +
- "and let's you choose the outcome. _*Only the bet moderator " +
- "can use this*_\n" +
- "/cancelbet - If something went wrong, it let's you cancel a bet. " +
- "_*Only the bet creator (during creation) or the bet moderator " +
- "(if creation has finished) can use this*_\n" +
- "/me - Tells your vault's contents.\n" +
- "/give [username] [amount] - Let's you altruistically give money " +
- "to another user.\n" +
- "/ranking - Shows the top 5 richest players.\n" +
- "\nRemember: this bot is geared towards group chats and you won't " +
- "be able to use me in a one-on-one chat.\n" +
- "Also, if I die during the creation of a bet, you can expect me " +
- "not to remember it.";
+ return "Aquí tienes una lista de comandos que acepto:\n\n" +
+ "/start - Repite el saludo inicial\n" +
+ "/help - Saca esta lista\n" +
+ "/pole - Para hacer la pole diaria\n" +
+ "/ranking - Muestra la lista de poles conseguidas.\n" +
+ "\nEa.";
case WARNING_UNKNOWN_ERROR:
return "Algo ha ido MUY mal.";
@@ -299,6 +315,9 @@ public class Vylbot {
return "No tienes nombre de usuario. Regístrate con uno en la " +
"configuración de Telegram para poder participar.";
+ case WARNING_POLE_BLOCKED:
+ return "La pole de hoy ya ha sido conseguida. Vuélvelo a intentar mañana.";
+
default: return "Entrada incorrecta.";
}
}
@@ -311,8 +330,11 @@ public class Vylbot {
case COMMAND_HELP:
return commands.get(COMMAND_HELP);
- case COMMAND_POLE:
- return commands.get(COMMAND_POLE);
+ case COMMAND_RANKING:
+ return commands.get(COMMAND_RANKING);
+
+ case COMMAND_TALIBOT_STATS:
+ return commands.get(COMMAND_TALIBOT_STATS);
default: return "Entrada incorrecta.";
}