Time Table Fixed
This commit is contained in:
@@ -81,6 +81,7 @@ public class StudentMenuHandler {
|
||||
weeklyBtn.put("id", "student_weekly_timetable");
|
||||
weeklyBtn.put("title", "Weekly Timetable");
|
||||
buttons.add(weeklyBtn);
|
||||
System.out.println("FINAL TODAY TIMETABLE MESSAGE:\n" + todaySchedule);
|
||||
|
||||
Map<String, Object> buttonMessage = WhatsAppMessageBuilder.buildButtonMessage(todaySchedule, buttons);
|
||||
messageService.sendInteractiveMessage(phoneNumber, buttonMessage);
|
||||
|
||||
@@ -95,74 +95,136 @@ public class MessageFormatter {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String formatTimetable(String rawJson) {
|
||||
private static class TimetableEntry {
|
||||
String subjectName;
|
||||
String subjectCode;
|
||||
String staffName;
|
||||
String staffCode;
|
||||
|
||||
public TimetableEntry(String subjectName, String subjectCode, String staffName, String staffCode) {
|
||||
this.subjectName = subjectName != null ? subjectName.trim() : "";
|
||||
this.subjectCode = subjectCode != null ? subjectCode.trim() : "";
|
||||
this.staffName = staffName != null ? staffName.trim() : "";
|
||||
this.staffCode = staffCode != null ? staffCode.trim() : "";
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return !subjectName.isEmpty() && !subjectCode.isEmpty();
|
||||
}
|
||||
|
||||
public String getUniqueKey() {
|
||||
return subjectName + "||" + subjectCode;
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatTodayTimetable(String rawJson) {
|
||||
String day = java.time.LocalDate.now()
|
||||
.getDayOfWeek()
|
||||
.getDisplayName(java.time.format.TextStyle.FULL, java.util.Locale.ENGLISH)
|
||||
.toLowerCase(java.util.Locale.ROOT);
|
||||
return formatTodayTimetableForDay(rawJson, day);
|
||||
}
|
||||
|
||||
public static String formatTodayTimetableForDay(String rawJson, String day) {
|
||||
if (rawJson == null) return "❌ Failed to retrieve timetable data.";
|
||||
|
||||
try {
|
||||
JsonNode root = mapper.readTree(rawJson);
|
||||
if (!root.has("data") || !root.get("data").isObject() || !root.get("data").has("schedule")) {
|
||||
return "❌ Timetable details not available in this format.";
|
||||
}
|
||||
|
||||
JsonNode schedule = root.get("data").get("schedule");
|
||||
|
||||
System.out.println("TIMETABLE DEBUG");
|
||||
System.out.println("Current day: " + day.toUpperCase());
|
||||
System.out.println("Normalized day: " + day);
|
||||
boolean hasSchedule = schedule.has(day);
|
||||
System.out.println("Schedule found: " + hasSchedule);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("\ud83d\uddd3\ufe0f *Today's Classes*\n\n");
|
||||
sb.append("📅 *Today's Classes*\n");
|
||||
sb.append("━━━━━━━━━━━━━━\n\n");
|
||||
|
||||
boolean validFormat = false;
|
||||
boolean hasClassesToday = false;
|
||||
|
||||
if (root.has("data") && root.get("data").isObject() && root.get("data").has("schedule")) {
|
||||
validFormat = true;
|
||||
JsonNode schedule = root.get("data").get("schedule");
|
||||
if (hasSchedule) {
|
||||
JsonNode daySchedule = schedule.get(day);
|
||||
|
||||
String today = java.time.LocalDate.now().getDayOfWeek().toString().toLowerCase();
|
||||
int maxPeriod = 7;
|
||||
java.util.Iterator<String> fieldNames = daySchedule.fieldNames();
|
||||
java.util.List<String> foundPeriods = new java.util.ArrayList<>();
|
||||
while (fieldNames.hasNext()) {
|
||||
String fName = fieldNames.next();
|
||||
foundPeriods.add(fName);
|
||||
try {
|
||||
int p = Integer.parseInt(fName);
|
||||
if (p > maxPeriod) {
|
||||
maxPeriod = p;
|
||||
}
|
||||
} catch (NumberFormatException e) {}
|
||||
}
|
||||
System.out.println("Periods found: [" + String.join(", ", foundPeriods) + "]");
|
||||
|
||||
if (schedule.has(today)) {
|
||||
JsonNode todaySchedule = schedule.get(today);
|
||||
for (int period = 1; period <= maxPeriod; period++) {
|
||||
String periodKey = String.valueOf(period);
|
||||
sb.append(getNumberEmoji(period)).append(" ");
|
||||
|
||||
if (todaySchedule.isObject() && todaySchedule.size() > 0) {
|
||||
java.util.Iterator<java.util.Map.Entry<String, JsonNode>> fields = todaySchedule.fields();
|
||||
while (fields.hasNext()) {
|
||||
java.util.Map.Entry<String, JsonNode> field = fields.next();
|
||||
String timeOrPeriod = field.getKey();
|
||||
JsonNode details = field.getValue();
|
||||
|
||||
if (details.isObject()) {
|
||||
String course = details.has("course_name") ? details.get("course_name").asText() :
|
||||
(details.has("name") ? details.get("name").asText() : "Unknown");
|
||||
String room = details.has("room") ? details.get("room").asText() : "";
|
||||
|
||||
sb.append("*").append(timeOrPeriod).append(":* ").append(course);
|
||||
if (!room.isEmpty()) sb.append(" (Room ").append(room).append(")");
|
||||
sb.append("\n");
|
||||
} else {
|
||||
sb.append("*").append(timeOrPeriod).append(":* ").append(details.asText()).append("\n");
|
||||
if (daySchedule.has(periodKey)) {
|
||||
JsonNode periodNode = daySchedule.get(periodKey);
|
||||
java.util.List<TimetableEntry> entries = new java.util.ArrayList<>();
|
||||
|
||||
if (periodNode.isArray()) {
|
||||
for (JsonNode node : periodNode) {
|
||||
String sName = node.has("subjectName") ? node.get("subjectName").asText() : "";
|
||||
String sCode = node.has("subjectCode") ? node.get("subjectCode").asText() : "";
|
||||
String stName = node.has("staffName") ? node.get("staffName").asText() : "";
|
||||
String stCode = node.has("staffCode") ? node.get("staffCode").asText() : "";
|
||||
entries.add(new TimetableEntry(sName, sCode, stName, stCode));
|
||||
}
|
||||
hasClassesToday = true;
|
||||
}
|
||||
} else if (todaySchedule.isArray() && todaySchedule.size() > 0) {
|
||||
for (JsonNode details : todaySchedule) {
|
||||
String time = details.has("time") ? details.get("time").asText() : "TBA";
|
||||
String course = details.has("course_name") ? details.get("course_name").asText() : "Unknown";
|
||||
String room = details.has("room") ? details.get("room").asText() : "";
|
||||
|
||||
sb.append("*").append(time).append(":* ").append(course);
|
||||
if (!room.isEmpty()) sb.append(" (Room ").append(room).append(")");
|
||||
sb.append("\n");
|
||||
hasClassesToday = true;
|
||||
|
||||
System.out.println("Period " + period + " entries: " + entries.size());
|
||||
if (!entries.isEmpty()) {
|
||||
TimetableEntry first = entries.get(0);
|
||||
System.out.println("Period " + period + " first subjectName: " + first.subjectName);
|
||||
System.out.println("Period " + period + " first subjectCode: " + first.subjectCode);
|
||||
}
|
||||
|
||||
java.util.Map<String, TimetableEntry> uniqueMap = new java.util.LinkedHashMap<>();
|
||||
for (TimetableEntry entry : entries) {
|
||||
if (entry.isValid()) {
|
||||
uniqueMap.putIfAbsent(entry.getUniqueKey(), entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (!uniqueMap.isEmpty()) {
|
||||
java.util.List<String> formattedSubjects = new java.util.ArrayList<>();
|
||||
for (TimetableEntry entry : uniqueMap.values()) {
|
||||
formattedSubjects.add("*" + entry.subjectName + "*\n `" + entry.subjectCode + "`");
|
||||
}
|
||||
sb.append(String.join(" / ", formattedSubjects)).append("\n\n");
|
||||
} else {
|
||||
sb.append("*Free Period*\n\n");
|
||||
}
|
||||
} else {
|
||||
sb.append("*Free Period*\n\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sb.append("No classes scheduled for today.\n\n");
|
||||
}
|
||||
|
||||
if (validFormat && !hasClassesToday) {
|
||||
sb.append("No classes scheduled for today.\n");
|
||||
} else if (!validFormat) {
|
||||
sb.append("Details not available in this format.\n");
|
||||
sb.append("\n\n*DEBUG RAW JSON:*\n").append(rawJson);
|
||||
}
|
||||
|
||||
sb.append("━━━━━━━━━━━━━━");
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
return "⚠️ Error formatting timetable data.\nRAW JSON: " + rawJson;
|
||||
System.err.println("Error formatting today's timetable: " + e.getMessage());
|
||||
return "⚠️ Error formatting timetable data.";
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatTimetable(String rawJson) {
|
||||
return formatTodayTimetable(rawJson);
|
||||
}
|
||||
|
||||
public static String formatResults(String rawJson, int semester) {
|
||||
if (rawJson == null) return "❌ Failed to retrieve semester results.";
|
||||
|
||||
@@ -444,76 +506,105 @@ public class MessageFormatter {
|
||||
return rows;
|
||||
}
|
||||
|
||||
private static String getNumberEmoji(int num) {
|
||||
switch (num) {
|
||||
case 1: return "1️⃣";
|
||||
case 2: return "2️⃣";
|
||||
case 3: return "3️⃣";
|
||||
case 4: return "4️⃣";
|
||||
case 5: return "5️⃣";
|
||||
case 6: return "6️⃣";
|
||||
case 7: return "7️⃣";
|
||||
case 8: return "8️⃣";
|
||||
case 9: return "9️⃣";
|
||||
default: return num + "️⃣";
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatWeeklyTimetable(String rawJson) {
|
||||
if (rawJson == null) return "❌ Failed to retrieve weekly timetable data.";
|
||||
|
||||
try {
|
||||
JsonNode root = mapper.readTree(rawJson);
|
||||
|
||||
if (!root.has("data") || !root.get("data").isObject() || !root.get("data").has("schedule")) {
|
||||
return "❌ Weekly timetable details not available in the response.";
|
||||
}
|
||||
|
||||
JsonNode schedule = root.get("data").get("schedule");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("📅 *Weekly Class Timetable*\n\n");
|
||||
sb.append("```\n");
|
||||
sb.append(String.format("%-3s | %-11s | %s\n", "Day", "Time/Period", "Subject (Room)"));
|
||||
sb.append("----+-------------+------------------------\n");
|
||||
sb.append("📚 WEEKLY TIMETABLE\n\n");
|
||||
|
||||
String[] days = {"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"};
|
||||
String[] dayAbbrevs = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
|
||||
String[] days = {"monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};
|
||||
String[] dayLabels = {"MON", "TUE", "WED", "THU", "FRI", "SAT"};
|
||||
boolean hasAnyClasses = false;
|
||||
|
||||
for (int i = 0; i < days.length; i++) {
|
||||
String day = days[i];
|
||||
String abbrev = dayAbbrevs[i];
|
||||
String label = dayLabels[i];
|
||||
|
||||
if (schedule.has(day)) {
|
||||
JsonNode daySchedule = schedule.get(day);
|
||||
|
||||
if (daySchedule.isObject() && daySchedule.size() > 0) {
|
||||
java.util.Iterator<java.util.Map.Entry<String, JsonNode>> fields = daySchedule.fields();
|
||||
while (fields.hasNext()) {
|
||||
java.util.Map.Entry<String, JsonNode> field = fields.next();
|
||||
String timeOrPeriod = field.getKey();
|
||||
JsonNode details = field.getValue();
|
||||
sb.append(label).append("\n");
|
||||
|
||||
int maxPeriod = 7;
|
||||
java.util.Iterator<String> fieldNames = daySchedule.fieldNames();
|
||||
while (fieldNames.hasNext()) {
|
||||
try {
|
||||
int p = Integer.parseInt(fieldNames.next());
|
||||
if (p > maxPeriod) {
|
||||
maxPeriod = p;
|
||||
}
|
||||
} catch (NumberFormatException e) {}
|
||||
}
|
||||
|
||||
for (int period = 1; period <= maxPeriod; period++) {
|
||||
String periodKey = String.valueOf(period);
|
||||
sb.append(getNumberEmoji(period)).append(" ");
|
||||
|
||||
if (daySchedule.has(periodKey)) {
|
||||
JsonNode details = daySchedule.get(periodKey);
|
||||
java.util.Set<String> subjects = new java.util.LinkedHashSet<>();
|
||||
|
||||
String course = "";
|
||||
String room = "";
|
||||
if (details.isObject()) {
|
||||
course = details.has("course_name") ? details.get("course_name").asText() :
|
||||
(details.has("name") ? details.get("name").asText() : "Unknown");
|
||||
room = details.has("room") ? details.get("room").asText() : "";
|
||||
} else {
|
||||
course = details.asText();
|
||||
if (details.isArray()) {
|
||||
for (JsonNode entry : details) {
|
||||
String name = entry.has("subjectName") ? entry.get("subjectName").asText() : "";
|
||||
String code = entry.has("subjectCode") ? entry.get("subjectCode").asText() : "";
|
||||
if (!name.trim().isEmpty()) {
|
||||
subjects.add(name.trim() + " — " + code.trim());
|
||||
}
|
||||
}
|
||||
} else if (details.isObject()) {
|
||||
String name = details.has("course_name") ? details.get("course_name").asText() :
|
||||
(details.has("name") ? details.get("name").asText() :
|
||||
(details.has("subjectName") ? details.get("subjectName").asText() : ""));
|
||||
String code = details.has("course_code") ? details.get("course_code").asText() :
|
||||
(details.has("code") ? details.get("code").asText() :
|
||||
(details.has("subjectCode") ? details.get("subjectCode").asText() : ""));
|
||||
if (!name.trim().isEmpty()) {
|
||||
subjects.add(name.trim() + " — " + code.trim());
|
||||
}
|
||||
}
|
||||
|
||||
String subjectRoom = room.isEmpty() ? course : course + " (" + room + ")";
|
||||
sb.append(String.format("%-3s | %-11s | %s\n", abbrev, truncate(timeOrPeriod, 11), subjectRoom));
|
||||
hasAnyClasses = true;
|
||||
}
|
||||
} else if (daySchedule.isArray() && daySchedule.size() > 0) {
|
||||
for (JsonNode details : daySchedule) {
|
||||
String time = details.has("time") ? details.get("time").asText() : "TBA";
|
||||
String course = details.has("course_name") ? details.get("course_name").asText() : "Unknown";
|
||||
String room = details.has("room") ? details.get("room").asText() : "";
|
||||
|
||||
String subjectRoom = room.isEmpty() ? course : course + " (" + room + ")";
|
||||
sb.append(String.format("%-3s | %-11s | %s\n", abbrev, truncate(time, 11), subjectRoom));
|
||||
hasAnyClasses = true;
|
||||
if (!subjects.isEmpty()) {
|
||||
sb.append(String.join(" / ", subjects)).append("\n");
|
||||
hasAnyClasses = true;
|
||||
} else {
|
||||
sb.append("—\n");
|
||||
}
|
||||
} else {
|
||||
sb.append("—\n");
|
||||
}
|
||||
}
|
||||
sb.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
sb.append("```");
|
||||
|
||||
if (!hasAnyClasses) {
|
||||
return "📅 *Weekly Class Timetable*\n\nNo classes scheduled for this week.";
|
||||
return "📚 WEEKLY TIMETABLE\n\nNo classes scheduled for this week.";
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
return sb.toString().trim();
|
||||
} catch (Exception e) {
|
||||
return "⚠️ Error formatting weekly timetable data.";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user