From 8ce038dbdd8187b98b10993991731fea90c80ecb Mon Sep 17 00:00:00 2001 From: vylion Date: Sun, 16 Oct 2016 20:24:34 +0200 Subject: [PATCH] Finished minimal persistence support (hopefully with no bugs - heh). Added recognition of a chat name change as an event. Added beta features configuration. --- src/elements/Chat.java | 101 +++++++++++++---- src/elements/ChatListItem.java | 17 +-- src/elements/Persistence.java | 143 ++++++++++++++++-------- src/elements/messages/GroupMessage.java | 15 ++- src/main/Geiserbot.java | 68 ++++++----- 5 files changed, 235 insertions(+), 109 deletions(-) diff --git a/src/elements/Chat.java b/src/elements/Chat.java index cebc8ca..08aacb6 100644 --- a/src/elements/Chat.java +++ b/src/elements/Chat.java @@ -1,6 +1,7 @@ package elements; +import elements.exceptions.ReadErrorChatException; import elements.exceptions.ReadErrorListException; import java.time.LocalDate; @@ -10,31 +11,45 @@ import java.util.*; * Created by Guillermo Serrahima on 4/21/16. */ public class Chat { - private static final String DATE_TAG = "Date="; - private static final String WINNER_TAG = "Winner="; - - public static final String MODE_NORMAL = "mode_normal"; - public static final String MODE_RANDOM_HOUR = "mode_random_hour"; - public static final String MODE_COLORS = "mode_colors"; - public static final String MODE_FAR_WEST = "mode_far_west"; + private static final String NAME_TAG = "Name="; + private static final String ID_TAG = "ChatID="; + private static final String BETA_TAG = "BetaEnabled="; private String name; + private Long chatId; private Map> lists; + private boolean beta; - public Chat() { + private Chat() { lists = new HashMap>(); name = null; + chatId = null; + beta = false; } - public Chat(String n) { - lists = new HashMap>(); + public Chat(String n, long chat_id) { + this(); name = n; + chatId = chat_id; + } + + public Chat(List lines) throws ReadErrorChatException { + this(); + loadInfo(lines); } public String getName() { return name; } + public void setName(String name) { + this.name = name; + } + + public Long getChatId() { + return chatId; + } + public boolean exists(String list) { return lists.containsKey(list); } @@ -47,20 +62,9 @@ public class Chat { lists.put(list, new ArrayList()); } - /* - public void winPole(String user, int date) throws PoleBlockedException { - if(!users.containsKey(user)) add(user); - if(!availablePole()) { - if(poleWinner != null) throw new PoleBlockedException(poleWinner); - else throw new PoleBlockedException(); - } - users.replace(user, users.get(user)+1); - - - - poleWinner = user; + public void addItem(String item, int value, String list) { + lists.get(list).add(new ChatListItem(item, value)); } - */ public String printList(String list) { ArrayList l = lists.get(list); @@ -119,7 +123,7 @@ public class Chat { if(lines.get(i).startsWith("#") || lines.get(i).length() < 1) { //do nothing } - //Comprueba si la línea es un comentario. (Windows) + //Comprueba si la línea es un comentario. (Caso: comentario precedido de cabecera UTF-8 en Windows) else if(lines.get(i).startsWith("\uFEFF#")) { //do nothing } @@ -130,6 +134,55 @@ public class Chat { } } } + + public List saveInfo() { + ArrayList lines = new ArrayList(); + + if(name != null) lines.add(NAME_TAG + name); + + if(chatId != null) lines.add(ID_TAG + chatId); + + if(beta == true) lines.add(BETA_TAG + "yes"); + else lines.add(BETA_TAG + "no"); + + return lines; + } + + private void loadInfo(List lines) throws ReadErrorChatException { + String line; + + for(int i = 0; i < lines.size(); i++) { + line = lines.get(i); + + if(line.startsWith("#") || line.length() < 1) { + //do nothing + } + //Comprueba si la línea es un comentario. (Caso: comentario precedido de cabecera UTF-8 en Windows) + else if(line.startsWith("\uFEFF#")) { + //do nothing + } + else if(line.startsWith(NAME_TAG)) { + if(name != null) throw new ReadErrorChatException("There was more than one name."); + name = line.substring(NAME_TAG.length()); + } + else if(line.startsWith(BETA_TAG)) { + line = line.substring(BETA_TAG.length()); + if(line.equals("yes")) beta = true; + else beta = false; + } + else if(line.startsWith(ID_TAG)) { + line = line.substring(ID_TAG.length()); + try { + chatId = Long.parseLong(line); + } catch(Exception e) { + throw new ReadErrorChatException("The chat id couldn't be read."); + } + } + else { + throw new ReadErrorChatException("There was an unrecognizable line in the chat info file."); + } + } + } } class ChatListItemComparator implements Comparator { diff --git a/src/elements/ChatListItem.java b/src/elements/ChatListItem.java index 911e1d5..c4b9618 100644 --- a/src/elements/ChatListItem.java +++ b/src/elements/ChatListItem.java @@ -9,20 +9,14 @@ public class ChatListItem { private String name; private Integer value; - private ChatListItem() { - - } public ChatListItem(String name, int value) { this.name = name; this.value = value; } - public ChatListItem(String parse) throws ReadErrorListException { - String[] reading = parse.split(";"); - if(reading.length > 2) throw new ReadErrorListException("Unidentified item."); - this.name = reading[0]; - this.value = Integer.parseInt(reading[1]); + public ChatListItem(String line) throws ReadErrorListException { + loadItem(line); } public int compareTo(ChatListItem c) { @@ -37,4 +31,11 @@ public class ChatListItem { public String saveItem() { return name + ";" + value; } + + private void loadItem(String line) throws ReadErrorListException { + String[] reading = line.split(";"); + if(reading.length > 2) throw new ReadErrorListException("Unidentified item."); + this.name = reading[0]; + this.value = Integer.parseInt(reading[1]); + } } diff --git a/src/elements/Persistence.java b/src/elements/Persistence.java index 3017b9c..5a59886 100644 --- a/src/elements/Persistence.java +++ b/src/elements/Persistence.java @@ -1,6 +1,7 @@ package elements; import elements.exceptions.ReadErrorChatException; +import elements.exceptions.ReadErrorListException; import elements.exceptions.SaveErrorChatException; import java.io.IOException; @@ -8,10 +9,7 @@ import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; /** @@ -29,12 +27,12 @@ public class Persistence { return persistence; } + private void saveChatInfo(Chat c) throws SaveErrorChatException { + Path file; + List lines = c.saveInfo(); - public void saveChatNames(List lines) throws SaveErrorChatException { try { - Path file; - - file = Paths.get("geiserFiles/chat_names.txt"); + file = Paths.get("geiserFiles/" + c.getChatId() + "/chat_info.txt"); if (!Files.exists(file.getParent())) Files.createDirectories(file.getParent()); Files.write(file, lines, Charset.forName("UTF-8")); @@ -43,68 +41,119 @@ public class Persistence { } } - public void saveChat(long chat_id, Chat c) throws SaveErrorChatException { + private Chat loadChatInfo(long chat_id) throws ReadErrorChatException { + Path file = Paths.get("geiserFiles/" + chat_id + "/chat_info.txt"); + List lines; + try { - List lines = new ArrayList(); - Path file; + lines = Files.readAllLines(file); + } catch (IOException e) { + throw new ReadErrorChatException(e); + } - //Save chat stats - lines.add("#Chat name:"); - lines.add("#" + c.getName()); + return new Chat(lines); + } - file = Paths.get("geiserFiles/" + chat_id + "/chat_names.txt"); - if (!Files.exists(file.getParent())) - Files.createDirectories(file.getParent()); - Files.write(file, lines, Charset.forName("UTF-8")); + private void saveChatLists(Chat c) throws SaveErrorChatException { + Path file; + ArrayList> lists = c.saveLists(); - //Save chat lists - ArrayList> lists = c.saveLists(); + for(int i = 0; i < lists.size(); i++) { + List lines = lists.get(i); + String filename = lines.get(1).substring("#".length()); - for(int i = 0; i < lists.size(); i++) { - lines = lists.get(i); - String filename = lines.get(1).substring("#".length()); + try { + file = Paths.get("geiserFiles/" + c.getChatId() + "/lists/" + filename + ".txt"); - file = Paths.get("geiserFiles/" + chat_id + "/lists/" + filename + ".txt"); if (!Files.exists(file.getParent())) Files.createDirectories(file.getParent()); Files.write(file, lines, Charset.forName("UTF-8")); + } catch (IOException e) { + throw new SaveErrorChatException(e); } + } + } + + private void loadChatLists(Chat c) throws ReadErrorChatException, ReadErrorListException { + Path file; + ArrayList> lists; + List lines; + + try { + List files = Files.walk(Paths.get("geiserFiles/" + c.getChatId() + "/lists/"), 1).collect(Collectors.toList()); + + for(int i = 0; i < files.size(); i++) { + file = files.get(i); + String filename = file.getFileName().toString(); + if(filename.endsWith(".txt")) { + System.out.println("Reading " + filename); + + lines = Files.readAllLines(file); + filename = filename.substring(0,filename.length() - 4); + c.loadList(filename, lines); + } + } + } catch (IOException e) { + throw new ReadErrorChatException(e); + } + } + + public void saveChat(Chat c) throws SaveErrorChatException { + //Save chat stats + saveChatInfo(c); + + //Save chat lists + saveChatLists(c); + } + + public void saveChatIndex(Map chats) throws SaveErrorChatException { + Path file; + ArrayList lines = new ArrayList(); + + Iterator> it = chats.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = it.next(); + + lines.add(entry.getKey() + "=" + entry.getValue().getName()); + } + + try { + file = Paths.get("geiserFiles/chat_index.txt"); + if (!Files.exists(file.getParent())) + Files.createDirectories(file.getParent()); + Files.write(file, lines, Charset.forName("UTF-8")); } catch (IOException e) { throw new SaveErrorChatException(e); } } - /* - public HashMap readChats() throws ReadErrorChatException { + public HashMap readChats() throws ReadErrorChatException, ReadErrorListException { HashMap chats = new HashMap(); + Path file = Paths.get("geiserFiles/chat_index.txt"); - if(!Files.exists(Paths.get("chats/"))) return chats; + if (!Files.exists(file)) + return chats; + + List lines; try { - String filename; - Chat chat; - List files = Files.walk(Paths.get("geiserFiles/"), 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)); - } - } + lines = Files.readAllLines(file); } catch (IOException e) { - e.printStackTrace(); throw new ReadErrorChatException(e); } + chats = new HashMap(); + + for (int i = 0; i < lines.size(); i++) { + String[] parse = lines.get(i).split("="); + if (parse.length != 2) throw new ReadErrorChatException("There was a problem reading the chat index."); + + Chat c = loadChatInfo(Long.parseLong(parse[0])); + loadChatLists(c); + + chats.put(c.getChatId(), c); + } + return chats; } - */ - } diff --git a/src/elements/messages/GroupMessage.java b/src/elements/messages/GroupMessage.java index 33066f7..ba785ca 100644 --- a/src/elements/messages/GroupMessage.java +++ b/src/elements/messages/GroupMessage.java @@ -9,8 +9,9 @@ import org.json.JSONObject; */ public class GroupMessage extends Message { //Event ID constants - public static final int USER_JOINED = 1; - public static final int USER_LEFT = 2; + private static final int USER_JOINED = 1; + private static final int USER_LEFT = 2; + private static final int CHAT_NAME_CHANGED = 3; private Long cid; //chat id private Integer mid; //message id @@ -61,6 +62,10 @@ public class GroupMessage extends Message { text = "@" + message.getJSONObject("left_chat_participant").getString("username"); else text = message.getJSONObject("left_chat_participant").getString("first_name"); } + else if(message.has("new_chat_title")) { + event = CHAT_NAME_CHANGED; + text = message.getString("new_chat_title"); + } } consoleLog = message.toString(); @@ -133,10 +138,12 @@ public class GroupMessage extends Message { } public boolean userLeft() { - return event.intValue() == USER_LEFT; + return event == USER_LEFT; } public boolean userJoined() { - return event.intValue() == USER_JOINED; + return event == USER_JOINED; } + + public boolean chatNameChanged() { return event == CHAT_NAME_CHANGED; } } diff --git a/src/main/Geiserbot.java b/src/main/Geiserbot.java index 54dbe4d..e253fa0 100644 --- a/src/main/Geiserbot.java +++ b/src/main/Geiserbot.java @@ -14,10 +14,7 @@ import elements.messages.PrivateMessage; import org.json.JSONArray; import org.json.JSONObject; -import java.security.PrivateKey; -import java.security.acl.Group; import java.time.LocalDate; -import java.time.ZoneId; import java.util.*; /** @@ -299,31 +296,59 @@ public class Geiserbot { } private void handleGroupEvent(GroupMessage m) throws NoTextMessageException, UnirestException { - System.out.println("Bot @" + USERNAME + " detects event. Joining: " + m.userJoined() + "; Leaving: " + m.userLeft()); - if(m.userJoined()) System.out.println("JOINING"); + System.out.print("Bot @" + USERNAME + " detects event: "); if(m.userJoined()) { - System.out.println("Bot @" + USERNAME + " detects new chat participant " + m.getText()); + System.out.println("JOINING"); + System.out.println("New chat participant: " + m.getText()); if(m.getText().equals("@" + USERNAME)) handleStart(m.getCid()); } else if(m.userLeft()) { System.out.println("LEAVING"); - System.out.println("Bot @" + USERNAME + " detects leaving chat participant " + m.getText()); + System.out.println("Leaving chat participant: " + m.getText()); + } + else if(m.chatNameChanged()) { + System.out.println("CHANGING CHAT NAME"); + System.out.println("New chat name: " + m.getText()); + + try { + chats.get(m.getCid()).setName(m.getText()); + saveChatIndex(); + } catch (SaveErrorChatException e) { + sendMessage(m.getCid(), "Ha habido un error guardando el nuevo nombre de este chat."); + } + } + else { + System.out.println("UNKNOWN"); } } private void handleList(GroupMessage m) throws UnirestException, NoTextMessageException { String[] reading = m.getText().split(" ", 2); - if(reading.length < 2) { + if (reading.length < 2) { sendMessage(m.getCid(), "Formato incorrecto. " + "Debes poner un espacio entre el comando /list y el nombre de la lista."); return; } String list = reading[1]; - if(!exists(m.getCid())) - chats.put(m.getCid(), new Chat(m.getChatName())); - if(!exists(m.getCid(), list)) - chats.get(m.getCid()).add(list); + if(!exists(m.getCid())) { + try { + chats.put(m.getCid(), new Chat(m.getChatName(), m.getCid())); + saveChatIndex(); + } catch (SaveErrorChatException e) { + sendMessage(m.getCid(), "Ha habido un error guardando los datos de este chat."); + return; + } + } + if(!exists(m.getCid(), list)) { + try { + chats.get(m.getCid()).add(list); + saveChat(m.getCid()); + } catch (SaveErrorChatException e) { + sendMessage(m.getCid(), "Ha habido un error creando la lista."); + return; + } + } sendMessage(m.getCid(), getWarning(WARNING_NOT_IMPLEMENTED)); } @@ -339,8 +364,8 @@ public class Geiserbot { if(!exists(m.getCid())) { try { - chats.put(m.getCid(), new Chat(m.getChatName())); - saveChatNames(); + chats.put(m.getCid(), new Chat(m.getChatName(), m.getCid())); + saveChatIndex(); } catch (SaveErrorChatException e) { sendMessage(m.getCid(), "Ha habido un error guardando los datos de este chat."); return; @@ -368,20 +393,11 @@ public class Geiserbot { } private void saveChat(long chat_id) throws SaveErrorChatException { - Persistence.getInstance().saveChat(chat_id, chats.get(chat_id)); + Persistence.getInstance().saveChat(chats.get(chat_id)); } - private void saveChatNames() throws SaveErrorChatException { - ArrayList lines = new ArrayList(); - - Iterator> it = chats.entrySet().iterator(); - while(it.hasNext()) { - Map.Entry entry = it.next(); - - lines.add(entry.getKey() + " = " + entry.getValue().getName()); - } - - Persistence.getInstance().saveChatNames(lines); + private void saveChatIndex() throws SaveErrorChatException { + Persistence.getInstance().saveChatIndex(chats); } private String getWarning(int warning_id) {