package de.tum.in.tumcampusapp.managers; import android.content.Context; import android.database.Cursor; import com.google.common.base.Optional; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import de.tum.in.tumcampusapp.api.TUMCabeClient; import de.tum.in.tumcampusapp.auxiliary.Const; import de.tum.in.tumcampusapp.auxiliary.Utils; import de.tum.in.tumcampusapp.cards.ChatMessagesCard; import de.tum.in.tumcampusapp.cards.generic.Card; import de.tum.in.tumcampusapp.exceptions.NoPrivateKey; import de.tum.in.tumcampusapp.models.tumcabe.ChatMember; import de.tum.in.tumcampusapp.models.tumcabe.ChatRoom; import de.tum.in.tumcampusapp.models.tumcabe.ChatVerification; import de.tum.in.tumcampusapp.models.tumo.LecturesSearchRow; import de.tum.in.tumcampusapp.models.tumo.LecturesSearchRowSet; import de.tum.in.tumcampusapp.tumonline.TUMOnlineConst; import de.tum.in.tumcampusapp.tumonline.TUMOnlineRequest; /** * TUMOnline cache manager, allows caching of TUMOnline requests */ public class ChatRoomManager extends AbstractManager implements Card.ProvidesCard { public static final int COL_ROOM = 0; public static final int COL_NAME = 1; public static final int COL_SEMESTER = 2; public static final int COL_SEMESTER_ID = 3; public static final int COL_JOINED = 4; public static final int COL_LV_NR = 5; public static final int COL_CONTRIBUTOR = 6; public static final int COL_MEMBERS = 7; /** * Constructor, open/create database, create table if necessary * * @param context Context */ public ChatRoomManager(Context context) { super(context); // create table if needed db.execSQL("CREATE TABLE IF NOT EXISTS chat_room (room INTEGER, name VARCHAR, " + "semester VARCHAR, semester_id VARCHAR, joined INTEGER, _id INTEGER, contributor VARCHAR, members INTEGER, PRIMARY KEY(name, semester_id))"); } /** * Gets all chat rooms that you have joined(1)/not joined(0) for the specified room * * @param joined chat room 1=joined, 0=not joined/left chat room, -1=not joined * @return List of chat messages */ public Cursor getAllByStatus(int joined) { String condition = "joined=1"; if (joined == 0) { condition = "joined=0 OR joined=-1"; } return db.rawQuery("SELECT r.*, m.ts, m.text " + "FROM chat_room r " + "LEFT JOIN (SELECT MAX(timestamp) ts, text, room FROM chat_message GROUP BY room) m ON (m.room=r.room) " + "WHERE " + condition + " " + " " + "ORDER BY r.semester!='', r.semester_id DESC, datetime(m.ts) DESC, r.name", null); } /** * Saves the given lecture into database */ public void replaceInto(LecturesSearchRow lecture) { Cursor cur = db.rawQuery("SELECT _id FROM chat_room WHERE name=? AND semester_id=?", new String[]{lecture.getTitel(), lecture.getSemester_id()}); cur.moveToFirst(); if (cur.getCount() >= 1) { db.execSQL("UPDATE chat_room SET semester=?, _id=?, contributor=? WHERE name=? AND semester_id=?", new String[]{lecture.getSemester_name(), lecture.getStp_lv_nr(), lecture.getVortragende_mitwirkende(), lecture.getTitel(), lecture.getSemester_id()}); } else { db.execSQL("REPLACE INTO chat_room (room,name,semester_id,semester,joined,_id,contributor,members) " + "VALUES (-1,?,?,?,-1,?,?,0)", new String[]{lecture.getTitel(), lecture.getSemester_id(), lecture.getSemester_name(), lecture.getStp_lv_nr(), lecture.getVortragende_mitwirkende()}); } cur.close(); } /** * Saves the given lectures into database */ public void replaceInto(List<LecturesSearchRow> lectures) { db.beginTransaction(); Cursor cur = db.rawQuery("SELECT _id FROM chat_room", null); HashSet<String> set = new HashSet<>(); if (cur.moveToFirst()) { do { set.add(cur.getString(COL_ROOM)); } while (cur.moveToNext()); } cur.close(); for (LecturesSearchRow lecture : lectures) { if (!set.contains(lecture.getStp_lv_nr())) { replaceInto(lecture); } } db.setTransactionSuccessful(); db.endTransaction(); } /** * Saves the given chat rooms into database */ public void replaceIntoRooms(List<ChatRoom> rooms) { if(rooms == null) { Utils.log("No rooms passed, can't insert anything."); return; } db.beginTransaction(); db.execSQL("UPDATE chat_room SET joined=0 WHERE joined=1"); Utils.log("reset join status of all rooms"); for (ChatRoom room : rooms) { Utils.log("Member of " + room.toString()); String roomName = room.getName(); String semester = "ZZZ"; if (roomName.contains(":")) { semester = roomName.substring(0, 3); roomName = roomName.substring(4); } Utils.logv("members2 " + room.getMembers()); Cursor cur = db.rawQuery("SELECT _id FROM chat_room WHERE name=? AND semester_id=?", new String[]{roomName, semester}); cur.moveToFirst(); if (cur.getCount() >= 1) { db.execSQL("UPDATE chat_room SET room=?, joined=1, members=? WHERE name=? AND semester_id=?", new String[]{String.valueOf(room.getId()), String.valueOf(room.getMembers()), roomName, semester}); } else { db.execSQL("REPLACE INTO chat_room (room,name,semester_id,semester,joined,_id,contributor,members) " + "VALUES (?,?,?,'',1,0,'',?)", new String[]{String.valueOf(room.getId()), roomName, semester, String.valueOf(room.getMembers())}); } cur.close(); } db.setTransactionSuccessful(); db.endTransaction(); } public void join(ChatRoom currentChatRoom) { db.execSQL("UPDATE chat_room SET room=?, joined=1 WHERE name=? AND semester_id=?", new String[]{String.valueOf(currentChatRoom.getId()), currentChatRoom.getName().substring(4), currentChatRoom.getName().substring(0, 3)}); } public void leave(ChatRoom currentChatRoom) { db.execSQL("UPDATE chat_room SET room=?, joined=0 WHERE name=? AND semester_id=?", new String[]{String.valueOf(currentChatRoom.getId()), currentChatRoom.getName().substring(4), currentChatRoom.getName().substring(0, 3)}); } @Override public void onRequestCard(Context context) { ChatRoomManager manager = new ChatRoomManager(context); // Use this to make sure chat_message table exists new ChatMessageManager(context, 0); // Get all of the users lectures and save them as possible chat rooms TUMOnlineRequest<LecturesSearchRowSet> requestHandler = new TUMOnlineRequest<>(TUMOnlineConst.LECTURES_PERSONAL, context, true); Optional<LecturesSearchRowSet> lecturesList = requestHandler.fetch(); if (lecturesList.isPresent() && lecturesList.get().getLehrveranstaltungen() != null) { List<LecturesSearchRow> lectures = lecturesList.get().getLehrveranstaltungen(); manager.replaceInto(lectures); } // Join all new chat rooms if (Utils.getSettingBool(context, Const.AUTO_JOIN_NEW_ROOMS, false)) { List<String> newRooms = manager.getNewUnjoined(); ChatMember currentChatMember = Utils.getSetting(context, Const.CHAT_MEMBER, ChatMember.class); for (String roomId : newRooms) { // Join chat room try { ChatRoom currentChatRoom = new ChatRoom(roomId); currentChatRoom = TUMCabeClient.getInstance(context).createRoom(currentChatRoom, new ChatVerification(context, currentChatMember)); if (currentChatRoom != null) { manager.join(currentChatRoom); } } catch (IOException e) { Utils.log(e, " - error occured while creating the room!"); } catch (NoPrivateKey noPrivateKey) { return; } } } // Get all rooms that have unread messages Cursor cur = manager.getUnreadRooms(); if (cur.moveToFirst()) { do { ChatMessagesCard card = new ChatMessagesCard(context); card.setChatRoom(cur.getString(0), cur.getInt(1), cur.getString(2) + ':' + cur.getString(0)); card.apply(); } while (cur.moveToNext()); } cur.close(); } private List<String> getNewUnjoined() { Cursor cursor = db.rawQuery("SELECT r.semester_id, r.name " + "FROM chat_room r, (SELECT semester_id FROM chat_room " + "WHERE (NOT semester_id IS NULL) AND semester_id!='' AND semester!='' " + "ORDER BY semester_id DESC LIMIT 1) AS new " + "WHERE r.semester_id=new.semester_id AND r.joined=-1", null); List<String> list = new ArrayList<>(cursor.getCount()); if (cursor.moveToFirst()) { do { list.add(cursor.getString(0) + ':' + cursor.getString(1)); } while (cursor.moveToNext()); } cursor.close(); return list; } private Cursor getUnreadRooms() { return db.rawQuery("SELECT r.name,r.room,r.semester_id " + "FROM chat_room r, (SELECT room FROM chat_message " + "WHERE read=0 GROUP BY room) AS c " + "WHERE r.room=c.room " + "ORDER BY r.semester_id DESC, r.name", null); } }