diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..79763db --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Launch Current File", + "request": "launch", + "mainClass": "${file}" + }, + { + "type": "java", + "name": "Launch App", + "request": "launch", + "mainClass": "xyz.thastertyn.App", + "projectName": "jecnak-tui" + } + ] +} \ No newline at end of file diff --git a/src/main/java/xyz/thastertyn/App.java b/src/main/java/xyz/thastertyn/App.java index dcdb9b4..29eec7c 100644 --- a/src/main/java/xyz/thastertyn/App.java +++ b/src/main/java/xyz/thastertyn/App.java @@ -1,6 +1,5 @@ package xyz.thastertyn; -import xyz.thastertyn.Jecna.*; import xyz.thastertyn.Window.MainWindow; /** @@ -20,49 +19,7 @@ public class App { - //#region Jidelna - //#region JSESSIONID - Connection.Response jidelna = Jsoup.connect("https://objednavky.jidelnasokolska.cz/") - .header("Connection", "keep-alive") - .method(Method.HEAD) - .execute(); - - String jidelnaJSESSIONID = jidelna.cookie("JSESSIONID"); - String XSRF_TOKEN = jidelna.cookie("XSRF-TOKEN"); - //#endregion - - //#region CSRF - String csrf = Jsoup.connect("https://objednavky.jidelnasokolska.cz/faces/login.jsp") - .header("Connection", "keep-alive") - .cookie("XSRF-TOKEN", XSRF_TOKEN) - .cookie("JSESSIONID", jidelnaJSESSIONID) - .get() - .select("input[name=_csrf]") - .attr("value"); - - - if(!XSRF_TOKEN.equals(csrf)) - { - throw new SecurityException("CSRF tokens do not match, something is up"); - } - //#endregion - - //#region Login - Connection.Response jidelnaLogin = Jsoup.connect("https://objednavky.jidelnasokolska.cz/j_spring_security_check") - .header("Connection", "keep-alive") - .header("Content-Type", "application/x-www-form-urlencoded") - .cookie("XSRF-TOKEN", XSRF_TOKEN) - .cookie("JSESSIONID", jidelnaJSESSIONID) - .data("j_username", Credentials.user) - .data("j_password", Credentials.pass) - .data("terminal", "false") - .data("type", "web") - .data("_csrf", XSRF_TOKEN) - .data("targetUrl", "/faces/secured/main.jsp?terminal=false&status=true&printer=false&keyboard=false") - .method(Method.POST) - .execute(); - //#endregion Document obedy = Jsoup.connect("https://objednavky.jidelnasokolska.cz/faces/secured/month.jsp?terminal=false&keyboard=&printer=") .header("Connection", "keep-alive") diff --git a/src/main/java/xyz/thastertyn/Connection.java b/src/main/java/xyz/thastertyn/Connection.java deleted file mode 100644 index 1d5dbbf..0000000 --- a/src/main/java/xyz/thastertyn/Connection.java +++ /dev/null @@ -1,15 +0,0 @@ -package xyz.thastertyn; - -import org.jsoup.Jsoup; - -public class Connection { - - private static final org.jsoup.Connection CONNECTION = Jsoup.connect("") - .header("Connection", "keep-alive") - .cookie("role", "student"); - - public static org.jsoup.Connection getConnection() - { - return CONNECTION; - } -} diff --git a/src/main/java/xyz/thastertyn/Download.java b/src/main/java/xyz/thastertyn/Download.java deleted file mode 100644 index be16dd4..0000000 --- a/src/main/java/xyz/thastertyn/Download.java +++ /dev/null @@ -1,5 +0,0 @@ -package xyz.thastertyn; - -public class Download { - -} diff --git a/src/main/java/xyz/thastertyn/Jecna/Dochazka.java b/src/main/java/xyz/thastertyn/Jecna/Dochazka.java index 900d7e7..ab34da4 100644 --- a/src/main/java/xyz/thastertyn/Jecna/Dochazka.java +++ b/src/main/java/xyz/thastertyn/Jecna/Dochazka.java @@ -3,9 +3,9 @@ package xyz.thastertyn.Jecna; import java.io.IOException; import java.util.HashMap; +import org.jsoup.Jsoup; import org.jsoup.nodes.Document; -import xyz.thastertyn.Connection; import xyz.thastertyn.Tuple.Pair; public class Dochazka { @@ -18,9 +18,10 @@ public class Dochazka { try { // absence-list - absenceDoc = Connection.getConnection() + absenceDoc = Jsoup.connect("https://www.spsejecna.cz" + "/absence/passing-student") .cookie("JSESSIOND", JSESSIOND) - .url("https://www.spsejecna.cz" + "/absence/passing-student") + .cookie("role", "student") + .header("Connection", "keep-alive") .get(); } catch (IOException e) { e.printStackTrace(); diff --git a/src/main/java/xyz/thastertyn/Jecna/Jidelna.java b/src/main/java/xyz/thastertyn/Jecna/Jidelna.java new file mode 100644 index 0000000..48b4871 --- /dev/null +++ b/src/main/java/xyz/thastertyn/Jecna/Jidelna.java @@ -0,0 +1,5 @@ +package xyz.thastertyn.Jecna; + +public class Jidelna { + +} diff --git a/src/main/java/xyz/thastertyn/Jecna/Login.java b/src/main/java/xyz/thastertyn/Jecna/Login.java index 8cc25be..385301e 100644 --- a/src/main/java/xyz/thastertyn/Jecna/Login.java +++ b/src/main/java/xyz/thastertyn/Jecna/Login.java @@ -4,9 +4,12 @@ import java.io.File; import java.io.IOException; import java.net.UnknownHostException; +import javax.security.auth.login.CredentialException; + import org.jsoup.Connection; import org.jsoup.Jsoup; import org.jsoup.Connection.Method; +import org.jsoup.nodes.Document; public class Login { @@ -23,7 +26,7 @@ public class Login { *
  • {@code false} neexistuje, nebo jsou prazdne
  • * */ - public boolean getCredentials() + public boolean checkForCredentials() { File credentials = null; @@ -67,9 +70,8 @@ public class Login { return Jsessionid; } - public byte login(String user, String pass) + public void loginJecna(String user, String pass) throws UnknownHostException, IOException, CredentialException { - try { //#region JSESSIONID Connection.Response response = Jsoup.connect("https://www.spsejecna.cz") .header("Connection", "keep-alive") @@ -89,7 +91,7 @@ public class Login { //#endregion //#region Login - Connection.Response login = Jsoup.connect("https://www.spsejecna.cz/user/login") + Jsoup.connect("https://www.spsejecna.cz/user/login") .method(Connection.Method.POST) .header("Content-Type", "application/x-www-form-urlencoded") //.header("Content-Length", "71") Adds 10 seconds to total request time @@ -105,17 +107,63 @@ public class Login { .execute(); //#endregion + Document test = Jsoup.connect("https://www.spsejecna.cz/score/student") + .header("Connection", "keep-alive") + .cookie("JSESSIONID", Jsessionid) + .cookie("role", "student") + .get(); + + if(test.toString().contains("Pro pokračování se přihlaste do systému")) + { + throw new CredentialException("Incorrect username or password"); + } + start = System.currentTimeMillis() / 1000L; lastCheck = start; + } - return 0; - } catch(UnknownHostException e) - { - // Not connected to internet - return 127; - } catch(IOException e) - { - return 126; - } + public void loginJidelna() throws UnknownHostException, IOException + { + //#region JSESSIONID + Connection.Response jidelna = Jsoup.connect("https://objednavky.jidelnasokolska.cz/") + .header("Connection", "keep-alive") + .method(Method.HEAD) + .execute(); + + String jidelnaJSESSIONID = jidelna.cookie("JSESSIONID"); + String XSRF_TOKEN = jidelna.cookie("XSRF-TOKEN"); + //#endregion + + //#region CSRF + String csrf = Jsoup.connect("https://objednavky.jidelnasokolska.cz/faces/login.jsp") + .header("Connection", "keep-alive") + .cookie("XSRF-TOKEN", XSRF_TOKEN) + .cookie("JSESSIONID", jidelnaJSESSIONID) + .get() + .select("input[name=_csrf]") + .attr("value"); + + + if(!XSRF_TOKEN.equals(csrf)) + { + throw new SecurityException("CSRF tokens do not match, something is up"); + } + //#endregion + + //#region Login + Connection.Response jidelnaLogin = Jsoup.connect("https://objednavky.jidelnasokolska.cz/j_spring_security_check") + .header("Connection", "keep-alive") + .header("Content-Type", "application/x-www-form-urlencoded") + .cookie("XSRF-TOKEN", XSRF_TOKEN) + .cookie("JSESSIONID", jidelnaJSESSIONID) + .data("j_username", Credentials.user) + .data("j_password", Credentials.pass) + .data("terminal", "false") + .data("type", "web") + .data("_csrf", XSRF_TOKEN) + .data("targetUrl", "/faces/secured/main.jsp?terminal=false&status=true&printer=false&keyboard=false") + .method(Method.POST) + .execute(); + //#endregion } } diff --git a/src/main/java/xyz/thastertyn/Jecna/Znamky.java b/src/main/java/xyz/thastertyn/Jecna/Znamky.java index 82fa990..6996cf1 100644 --- a/src/main/java/xyz/thastertyn/Jecna/Znamky.java +++ b/src/main/java/xyz/thastertyn/Jecna/Znamky.java @@ -1,9 +1,10 @@ package xyz.thastertyn.Jecna; import java.io.IOException; +import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; @@ -15,17 +16,20 @@ public class Znamky { private boolean wasDownloaded; - // key (String) reprezentuje predmet, value (arraylist) znamky a pair znamku s jeji vahou - private HashMap>> grades = new HashMap<>(); + private ArrayList>,Double>>> grades = new ArrayList<>(); - public void addGrade(String subject, int grade, double weight) + public void addGrade(int index, String subject, int grade, double weight) { - grades.get(subject).add(new Pair(grade, weight)); + Pair znamka = new Pair<>(grade, weight); + + grades.get(index).getValue1().getValue0().add(znamka); } public void addSubject(String subject) { - grades.put(subject, new ArrayList>()); + Pair>, Double> p = new Pair<>(new ArrayList>(), 0.0); + + grades.add(new Pair<>(subject, p)); } private double getAverage(ArrayList> a) @@ -39,7 +43,8 @@ public class Znamky { divisor += p.getValue1(); } - return (double) divident / divisor; + double prumer = (double) divident / divisor; + return (double) Math.round(prumer * 100) / 100; }catch(ArithmeticException e) { @@ -47,17 +52,10 @@ public class Znamky { } } - public byte downloadZnamky(final String Jsessionid) + public void downloadZnamky(final String Jsessionid) throws UnknownHostException, IOException { wasDownloaded = true; - Document znamkyDoc = null; - - try { - znamkyDoc = Downloader.download("https://www.spsejecna.cz" + "/score/student", Jsessionid).get(); - } catch (IOException e) { - e.printStackTrace(); - return 127; - } + Document znamkyDoc = Downloader.download("https://www.spsejecna.cz" + "/score/student", Jsessionid).get(); Elements rows = znamkyDoc.select("table.score").select("tr"); @@ -68,25 +66,43 @@ public class Znamky { rows_split[i] = rows.get(i).children(); } + int subj = 0; + for(int i = 1; i < rows_split.length; i++) { - String predmet = rows_split[i].get(0).text(); + String predmetFull = rows_split[i].get(0).text(); + + Matcher matcher = Pattern.compile("\\((.*)\\)").matcher(predmetFull); + + String predmet = matcher.find() ? matcher.group(1) : predmetFull; addSubject(predmet); - for(Element e : rows_split[i].get(1).select("a.score")) + for(Element znamkaElement : rows_split[i].get(1).select("a.score")) { - int znamka = Integer.parseInt(e.select("span.value").text()); + if(znamkaElement == null) + { + break; + } + + int znamka = Integer.parseInt(znamkaElement.select("span.value").text()); // Mala znamka se bude pocitat jako polovicni vaha - if(e.hasClass("scoreSmall")) + if(znamkaElement.hasClass("scoreSmall")) { - addGrade(predmet, znamka, 0.5); + addGrade(subj, predmet, znamka, 0.5); }else{ - addGrade(predmet, znamka, 1); + addGrade(subj, predmet, znamka, 1); } } + + grades.get(subj).getValue1().setValue1(getAverage(grades.get(subj).getValue1().getValue0())); + subj++; } - return 0; + } + + public ArrayList>,Double>>> getGrades() + { + return grades; } @Override @@ -96,11 +112,9 @@ public class Znamky { { String s = ""; - for(Map.Entry>> entry : grades.entrySet()) + for(Pair>,Double>> p : grades) { - double prumer = getAverage(entry.getValue()); - double p = (double) Math.round(prumer * 100) / 100; - s += entry.getKey() + " | " + entry.getValue().toString() + " { " + p + " }\n"; + s += p.getValue0() + " | " + p.getValue1().getValue0().toString() + " { " + p.getValue1().getValue1() + " } "; } return s; }else{ diff --git a/src/main/java/xyz/thastertyn/Predmet.java b/src/main/java/xyz/thastertyn/Predmet.java deleted file mode 100644 index 3e8f98a..0000000 --- a/src/main/java/xyz/thastertyn/Predmet.java +++ /dev/null @@ -1,8 +0,0 @@ -package xyz.thastertyn; - -import java.util.ArrayList; - -public class Predmet { - - -} diff --git a/src/main/java/xyz/thastertyn/RozvrhDownload.java b/src/main/java/xyz/thastertyn/RozvrhDownload.java deleted file mode 100644 index 0267187..0000000 --- a/src/main/java/xyz/thastertyn/RozvrhDownload.java +++ /dev/null @@ -1,5 +0,0 @@ -package xyz.thastertyn; - -public class RozvrhDownload { - -} diff --git a/src/main/java/xyz/thastertyn/Window/Content/JecnaContent.java b/src/main/java/xyz/thastertyn/Window/Content/JecnaContent.java new file mode 100644 index 0000000..2967d90 --- /dev/null +++ b/src/main/java/xyz/thastertyn/Window/Content/JecnaContent.java @@ -0,0 +1,29 @@ +package xyz.thastertyn.Window.Content; + +import com.googlecode.lanterna.gui2.Panel; + +/** + * Wrapper to include all classes that deal with content in some way + */ +public class JecnaContent { + + public Panel getPanel() + { + return null; + } + + public void download(String s) + { + + } + + public boolean hasStarted() + { + return false; + } + + public String getLabel() + { + return ""; + } +} diff --git a/src/main/java/xyz/thastertyn/Window/Content/Jidelna.java b/src/main/java/xyz/thastertyn/Window/Content/Jidelna.java new file mode 100644 index 0000000..62fb593 --- /dev/null +++ b/src/main/java/xyz/thastertyn/Window/Content/Jidelna.java @@ -0,0 +1,5 @@ +package xyz.thastertyn.Window.Content; + +public class Jidelna { + +} diff --git a/src/main/java/xyz/thastertyn/Window/Content/Rozvrh.java b/src/main/java/xyz/thastertyn/Window/Content/Rozvrh.java new file mode 100644 index 0000000..b8aeb0f --- /dev/null +++ b/src/main/java/xyz/thastertyn/Window/Content/Rozvrh.java @@ -0,0 +1,70 @@ +package xyz.thastertyn.Window.Content; + +import java.io.IOException; +import java.net.UnknownHostException; + +import com.googlecode.lanterna.gui2.Label; +import com.googlecode.lanterna.gui2.Panel; +import com.googlecode.lanterna.gui2.table.Table; + +public class Rozvrh extends JecnaContent { + + private Panel rozvrhPanel = new Panel(); + + private boolean hasStarted = false; + + private xyz.thastertyn.Jecna.Rozvrh rozvrh = new xyz.thastertyn.Jecna.Rozvrh(); + + //private String[] labels = {"Den", "7:30-8:15", "8:25-9:10", "9:20-10:05", "10:20-11:05", "11:15-12:00", "12:10-12:55", "13:05-13:50", "14:00-14:45", "14:55-15:40", "15:50-16:35"}; + private String[] labels = {"Den", "1.", "2.", "3.", "4.", "5.", "6.", "7.", "8.", "9.", "10."}; + + String[] days = {"PO", "UT", "ST", "CT", "PA"}; + + Table t = new Table<>(labels); + + @Override + public void download(String Jsessionid) + { + try{ + rozvrh.downloadRozvrh(Jsessionid); + + String[][] r = rozvrh.getRozvrh(); + + String[] s = new String[labels.length]; + + for(int i = 0; i < r.length; i++) + { + s[0] = days[i]; + for(int j = 1; j < r[i].length; j++) { s[j] = r[i][j]; } + + t.getTableModel().addRow(s); + } + rozvrhPanel.addComponent(t); + hasStarted = true; + }catch(UnknownHostException e) + { + rozvrhPanel.addComponent(new Label("A connection error occurred")); + }catch(IOException e) + { + rozvrhPanel.addComponent(new Label("An error occurred")); + } + } + + @Override + public boolean hasStarted() + { + return hasStarted; + } + + @Override + public Panel getPanel() + { + return rozvrhPanel; + } + + @Override + public String getLabel() + { + return "Rozvrh"; + } +} diff --git a/src/main/java/xyz/thastertyn/Window/Content/Znamky.java b/src/main/java/xyz/thastertyn/Window/Content/Znamky.java new file mode 100644 index 0000000..acac87f --- /dev/null +++ b/src/main/java/xyz/thastertyn/Window/Content/Znamky.java @@ -0,0 +1,127 @@ +package xyz.thastertyn.Window.Content; + +import java.io.IOException; +import java.util.ArrayList; + +import com.googlecode.lanterna.TextColor; +import com.googlecode.lanterna.graphics.SimpleTheme; +import com.googlecode.lanterna.gui2.Direction; +import com.googlecode.lanterna.gui2.Label; +import com.googlecode.lanterna.gui2.LinearLayout; +import com.googlecode.lanterna.gui2.Panel; +import xyz.thastertyn.Tuple.Pair; + +public class Znamky extends JecnaContent { + + private Panel znamkyPanel = new Panel().setLayoutManager(new LinearLayout(Direction.HORIZONTAL)); + + private xyz.thastertyn.Jecna.Znamky znamky = new xyz.thastertyn.Jecna.Znamky(); + + private boolean hasStarted = false; + + @Override + public void download(String JsessionId) + { + try{ + znamky.downloadZnamky(JsessionId); + + Panel predmetyPanel = new Panel().setLayoutManager(new LinearLayout(Direction.VERTICAL)); + Panel znamkyP = new Panel().setLayoutManager(new LinearLayout(Direction.VERTICAL)); + Panel vyslPanel = new Panel().setLayoutManager(new LinearLayout(Direction.VERTICAL)); + + ArrayList>,Double>>> grades = znamky.getGrades(); + + for(Pair>,Double>> predmet : grades) + { + predmetyPanel.addComponent(new Label(predmet.getValue0())); + + Panel znamkyZPredmetu = new Panel().setLayoutManager(new LinearLayout(Direction.HORIZONTAL)); + + if(predmet.getValue1().getValue0().isEmpty()) + { + znamkyZPredmetu.addComponent(new Label("")); + } + + for(Pair znamka : predmet.getValue1().getValue0()) + { + // TODO pridat predmet.getValue0() ktery premeni znamky na jmeno predmetu jako funkci (not a bug, its a feature) + Label znamkaLabel = new Label(znamka.getValue0() + ""); + switch(znamka.getValue0()) + { + case 1: + znamkaLabel.setTheme(new SimpleTheme(TextColor.ANSI.BLACK, TextColor.ANSI.GREEN)); + break; + case 2: + znamkaLabel.setTheme(new SimpleTheme(TextColor.ANSI.BLACK, TextColor.ANSI.BLUE)); + break; + case 3: + znamkaLabel.setTheme(new SimpleTheme(TextColor.ANSI.BLACK, TextColor.ANSI.YELLOW)); + break; + case 4: + znamkaLabel.setTheme(new SimpleTheme(TextColor.ANSI.BLACK, TextColor.ANSI.MAGENTA)); + break; + case 5: + znamkaLabel.setTheme(new SimpleTheme(TextColor.ANSI.BLACK, TextColor.ANSI.RED)); + break; + } + + znamkyZPredmetu.addComponent(znamkaLabel); + } + + znamkyP.addComponent(znamkyZPredmetu); + + double prumer = predmet.getValue1().getValue1(); + + Label vysl = new Label("" + prumer); + + if(prumer >= 1 && prumer < 1.5) + { + vysl.setTheme(new SimpleTheme(TextColor.ANSI.BLACK, TextColor.ANSI.GREEN)); + }else if(prumer >= 1.5 && prumer < 2.5) + { + vysl.setTheme(new SimpleTheme(TextColor.ANSI.BLACK, TextColor.ANSI.BLUE)); + + }else if(prumer >= 2.5 && prumer < 3.5) + { + vysl.setTheme(new SimpleTheme(TextColor.ANSI.BLACK, TextColor.ANSI.YELLOW)); + + }else if(prumer >= 3.5 && prumer < 4.5) + { + vysl.setTheme(new SimpleTheme(TextColor.ANSI.BLACK, TextColor.ANSI.MAGENTA)); + }else if(prumer >= 4.5) + { + vysl.setTheme(new SimpleTheme(TextColor.ANSI.BLACK, TextColor.ANSI.RED)); + } + + vyslPanel.addComponent(vysl); + } + + znamkyPanel.addComponent(predmetyPanel); + znamkyPanel.addComponent(znamkyP); + znamkyPanel.addComponent(vyslPanel); + + hasStarted = true; + }catch(IOException e) + { + znamkyPanel.addComponent(new Label("An error has occured")); + } + } + + @Override + public Panel getPanel() + { + return znamkyPanel; + } + + @Override + public boolean hasStarted() + { + return hasStarted; + } + + @Override + public String getLabel() + { + return "Znamky"; + } +} diff --git a/src/main/java/xyz/thastertyn/Window/Login.java b/src/main/java/xyz/thastertyn/Window/Login.java index 1253417..ed3dd78 100644 --- a/src/main/java/xyz/thastertyn/Window/Login.java +++ b/src/main/java/xyz/thastertyn/Window/Login.java @@ -1,36 +1,164 @@ package xyz.thastertyn.Window; +import java.io.IOException; +import java.net.UnknownHostException; +import java.util.Arrays; + +import javax.security.auth.login.CredentialException; + +import com.googlecode.lanterna.TerminalSize; +import com.googlecode.lanterna.gui2.Button; +import com.googlecode.lanterna.gui2.EmptySpace; +import com.googlecode.lanterna.gui2.GridLayout; +import com.googlecode.lanterna.gui2.Label; +import com.googlecode.lanterna.gui2.LocalizedString; +import com.googlecode.lanterna.gui2.Panel; +import com.googlecode.lanterna.gui2.TextBox; +import com.googlecode.lanterna.gui2.Window; import com.googlecode.lanterna.gui2.WindowBasedTextGUI; +import com.googlecode.lanterna.gui2.GridLayout.Alignment; +import com.googlecode.lanterna.gui2.dialogs.DialogWindow; +import com.googlecode.lanterna.gui2.dialogs.MessageDialog; +import com.googlecode.lanterna.gui2.dialogs.MessageDialogButton; -public class Login { - - String user = ""; - String pass = ""; +public class Login extends DialogWindow { - xyz.thastertyn.Jecna.Login login = new xyz.thastertyn.Jecna.Login(); + private TextBox username; + private TextBox password; + private String user; + private String pass; - LoginDialog dialog = new LoginDialog("Login", "Enter your username and password"); + private xyz.thastertyn.Jecna.Login login = new xyz.thastertyn.Jecna.Login(); - public void showDialog(WindowBasedTextGUI textGUI) + Login() { - String[] input = dialog.showDialog(textGUI); + super("Login"); + this.user = null; + this.pass = null; + this.username = new TextBox(); + this.password = new TextBox().setMask('*'); - user = input[0]; - pass = input[1]; + Panel buttonPanel = new Panel(); + buttonPanel + .setLayoutManager( + new GridLayout(2).setHorizontalSpacing(1)) + .addComponent( + new Button(LocalizedString.OK.toString(), this::onOK) + .setLayoutData(GridLayout.createLayoutData( + GridLayout.Alignment.CENTER, + GridLayout.Alignment.CENTER, + true, + false))) + .addComponent( + new Button(LocalizedString.Cancel.toString(), this::onCancel)); - login(); + Panel mainPanel = new Panel() + .setLayoutManager(new GridLayout(1) + .setLeftMarginSize(1) + .setRightMarginSize(1)); + + mainPanel.addComponent(new Label("Enter your username and password")); + + mainPanel.addComponent(new EmptySpace(TerminalSize.ONE)); + + Panel userPanel = new Panel() + .setLayoutManager(new GridLayout(3)) + .setLayoutData( + GridLayout.createLayoutData( + GridLayout.Alignment.FILL, + Alignment.CENTER, + true, + false)); + + this.username.setLayoutData( + GridLayout.createLayoutData( + GridLayout.Alignment.FILL, + GridLayout.Alignment.CENTER, + true, + false)); + + userPanel.addComponent(new Label("Username: ")) + .addComponent(username) + .addTo(mainPanel); + + this.password + .setLayoutData( + GridLayout.createLayoutData(GridLayout.Alignment.FILL, + GridLayout.Alignment.CENTER, + true, + false)) + .addTo(mainPanel); + + Panel passPanel = new Panel() + .setLayoutManager(new GridLayout(3)) + .setLayoutData(GridLayout.createLayoutData( + GridLayout.Alignment.FILL, + Alignment.CENTER, + true, + false)); + + passPanel.addComponent(new Label("Password: ")) + .addComponent(password) + .addTo(mainPanel); + + mainPanel.addComponent(new EmptySpace(TerminalSize.ONE)); + + buttonPanel.setLayoutData( + GridLayout.createLayoutData( + Alignment.END, + Alignment.CENTER, + false, false)) + .addTo(mainPanel); + + setHints(Arrays.asList(Window.Hint.CENTERED)); + setComponent(mainPanel); } - private void login() + public void onOK() { - login.login(user, pass); + this.user = username.getText(); + this.pass = password.getText(); - user = null; - pass = null; + if (user.isEmpty() || pass.isEmpty()) + { + MessageDialog.showMessageDialog(getTextGUI(), getTitle(), "Username and password cannot be blank", + MessageDialogButton.OK); + return; + } + + try + { + login.loginJecna(user, pass); + } catch (UnknownHostException e) { + MessageDialog.showMessageDialog(getTextGUI(), "No Internet connection", + "There seems to be no internet connection, reverting to cached data", MessageDialogButton.OK); + return; + } catch (CredentialException e) + { + MessageDialog.showMessageDialog(getTextGUI(), "Incorrect username or password", + "The username or password you entered is incorrect", MessageDialogButton.OK); + return; + } catch (IOException e) + { + MessageDialog.showMessageDialog(getTextGUI(), "There was an error", "Maybe try again and it will go away", + MessageDialogButton.OK); + return; + } + + close(); } - public String getJsessionId() - { + public String getJessionId() { return login.getJSESSIONID(); } + + public void onCancel() { + close(); + } + + @Override + public String[] showDialog(WindowBasedTextGUI textGUI) { + super.showDialog(textGUI); + return new String[] { user, pass }; + } } diff --git a/src/main/java/xyz/thastertyn/Window/LoginDialog.java b/src/main/java/xyz/thastertyn/Window/LoginDialog.java deleted file mode 100644 index f7296f4..0000000 --- a/src/main/java/xyz/thastertyn/Window/LoginDialog.java +++ /dev/null @@ -1,112 +0,0 @@ -package xyz.thastertyn.Window; - -import com.googlecode.lanterna.TerminalSize; -import com.googlecode.lanterna.gui2.Button; -import com.googlecode.lanterna.gui2.EmptySpace; -import com.googlecode.lanterna.gui2.GridLayout; -import com.googlecode.lanterna.gui2.Label; -import com.googlecode.lanterna.gui2.LocalizedString; -import com.googlecode.lanterna.gui2.Panel; -import com.googlecode.lanterna.gui2.TextBox; -import com.googlecode.lanterna.gui2.WindowBasedTextGUI; -import com.googlecode.lanterna.gui2.GridLayout.Alignment; -import com.googlecode.lanterna.gui2.dialogs.DialogWindow; -import com.googlecode.lanterna.gui2.dialogs.MessageDialog; -import com.googlecode.lanterna.gui2.dialogs.MessageDialogButton; - -public class LoginDialog extends DialogWindow { - - private TextBox username; - private TextBox password; - private String user; - private String pass; - - LoginDialog( - String title, - String description - ) - { - super(title); - this.user = null; - this.pass = null; - this.username = new TextBox(); - this.password = new TextBox().setMask('*'); - - Panel buttonPanel = new Panel(); - buttonPanel.setLayoutManager((new GridLayout(2).setHorizontalSpacing(1))); - buttonPanel - .addComponent((new Button(LocalizedString.OK.toString(), this::onOK) - .setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.CENTER, GridLayout.Alignment.CENTER, true, false)))); - buttonPanel.addComponent(new Button(LocalizedString.Cancel.toString(), this::onCancel)); - - Panel mainPanel = new Panel(); - mainPanel.setLayoutManager(new GridLayout(1).setLeftMarginSize(1).setRightMarginSize(1)); - - if(description != null) - { - mainPanel.addComponent(new Label(description)); - } - - mainPanel.addComponent(new EmptySpace(TerminalSize.ONE)); - - Panel userPanel = new Panel() - .setLayoutManager(new GridLayout(3)) - .setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.FILL, Alignment.CENTER, true, false)); - - this.username.setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.FILL, GridLayout.Alignment.CENTER, true, false)); - - userPanel.addComponent(new Label("Username: ")) - .addComponent(username) - .addTo(mainPanel); - - this.password.setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.FILL, GridLayout.Alignment.CENTER, true, false)) - .addTo(mainPanel); - - Panel passPanel = new Panel() - .setLayoutManager(new GridLayout(3)) - .setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.FILL, Alignment.CENTER, true, false)); - - passPanel.addComponent(new Label("Password: ")) - .addComponent(password) - .addTo(mainPanel); - - mainPanel.addComponent(new EmptySpace(TerminalSize.ONE)); - - buttonPanel.setLayoutData( - GridLayout.createLayoutData( - Alignment.END, - Alignment.CENTER, - false, false)) - .addTo(mainPanel); - - setComponent(mainPanel); - } - - public void onOK() - { - if(username.getText().isEmpty() || password.getText().isEmpty()) - { - MessageDialog.showMessageDialog(getTextGUI(), getTitle(), "Username and password cannot be blank", MessageDialogButton.OK); - return; - } - - this.user = username.getText(); - this.pass = password.getText(); - - close(); - } - - public void onCancel() - { - close(); - } - - @Override - public String[] showDialog(WindowBasedTextGUI textGUI) - { - user = null; - pass = null; - super.showDialog(textGUI); - return new String[] {user, pass}; - } -} diff --git a/src/main/java/xyz/thastertyn/Window/MainWindow.java b/src/main/java/xyz/thastertyn/Window/MainWindow.java index 1b274cb..33e2342 100644 --- a/src/main/java/xyz/thastertyn/Window/MainWindow.java +++ b/src/main/java/xyz/thastertyn/Window/MainWindow.java @@ -2,13 +2,12 @@ package xyz.thastertyn.Window; import java.io.IOException; import java.util.Arrays; - import com.googlecode.lanterna.TextColor; import com.googlecode.lanterna.gui2.BasicWindow; -import com.googlecode.lanterna.gui2.Borders; import com.googlecode.lanterna.gui2.DefaultWindowManager; import com.googlecode.lanterna.gui2.Direction; import com.googlecode.lanterna.gui2.EmptySpace; +import com.googlecode.lanterna.gui2.Label; import com.googlecode.lanterna.gui2.LinearLayout; import com.googlecode.lanterna.gui2.MultiWindowTextGUI; import com.googlecode.lanterna.gui2.Panel; @@ -19,58 +18,53 @@ import com.googlecode.lanterna.screen.TerminalScreen; import com.googlecode.lanterna.terminal.DefaultTerminalFactory; import com.googlecode.lanterna.terminal.Terminal; -import xyz.thastertyn.Jecna.Credentials; -import xyz.thastertyn.Jecna.Login; - public class MainWindow { - - Login l = new Login(); + private Terminal terminal; + private Screen screen; + private Window window; + private MultiWindowTextGUI textGUI; + + public void run() { - Terminal terminal = null; try { + //#region init // Setup terminal and screen layers terminal = new DefaultTerminalFactory().createTerminal(); - Screen screen = new TerminalScreen(terminal); + screen = new TerminalScreen(terminal); screen.startScreen(); + // Create window to hold the panel + window = new BasicWindow(); + window.setHints(Arrays.asList(Window.Hint.CENTERED)); + + // Create gui and start gui + textGUI = new MultiWindowTextGUI(screen, new DefaultWindowManager(), new EmptySpace(TextColor.ANSI.BLACK_BRIGHT)); + //#endregion + // Create panel to hold components final Panel mainPanel = new Panel(); - mainPanel.setLayoutManager(new LinearLayout(Direction.HORIZONTAL)); + mainPanel.setLayoutManager(new LinearLayout(Direction.VERTICAL)); - // Create window to hold the panel - BasicWindow window = new BasicWindow(); window.setComponent(mainPanel); - window.setHints(Arrays.asList(Window.Hint.CENTERED)); mainPanel.addComponent(new Separator(Direction.VERTICAL).setLayoutData(LinearLayout.createLayoutData(LinearLayout.Alignment.Fill))); - final Panel content = new Panel(); - mainPanel.addComponent(content); + Panel content = new Panel(); + content.addTo(mainPanel); - xyz.thastertyn.Window.Login login = new xyz.thastertyn.Window.Login(); + Login login = new Login(); + login.showDialog(textGUI); - /*Rozvrh r = new Rozvrh(); - r.download(login.getJsessionId()); - - content.addComponent(r.getPanel());*/ + window.addWindowListener(new WindowSwitchListener(content, login.getJessionId())); + + textGUI.addWindowAndWait(window); - // Create gui and start gui - final MultiWindowTextGUI gui = new MultiWindowTextGUI(screen, new DefaultWindowManager(), new EmptySpace(TextColor.ANSI.BLACK_BRIGHT)); - login.showDialog(gui); - /*KeyStroke k = terminal.readInput(); - if(k.equals(KeyStroke.fromString(""))) - { - window.close(); - }*/ - gui.addWindowAndWait(window); - - - } catch (IOException e) { - e.printStackTrace(); - } + } catch (IOException e) { + e.printStackTrace(); + } } } diff --git a/src/main/java/xyz/thastertyn/Window/Rozvrh.java b/src/main/java/xyz/thastertyn/Window/Rozvrh.java deleted file mode 100644 index 8a8d45f..0000000 --- a/src/main/java/xyz/thastertyn/Window/Rozvrh.java +++ /dev/null @@ -1,62 +0,0 @@ -package xyz.thastertyn.Window; - -import java.io.IOException; -import java.net.UnknownHostException; -import java.util.List; - -import com.googlecode.lanterna.TerminalSize; -import com.googlecode.lanterna.TextColor; -import com.googlecode.lanterna.graphics.SimpleTheme; -import com.googlecode.lanterna.gui2.Direction; -import com.googlecode.lanterna.gui2.Panel; -import com.googlecode.lanterna.gui2.Separator; -import com.googlecode.lanterna.gui2.TextGUIGraphics; -import com.googlecode.lanterna.gui2.table.Table; -import com.googlecode.lanterna.gui2.table.TableCellRenderer; - -public class Rozvrh { - - private Panel rozvrhPanel = new Panel(); - - private xyz.thastertyn.Jecna.Rozvrh rozvrh = new xyz.thastertyn.Jecna.Rozvrh(); - - private String[] labels = {"Den", "7:30-8:15", "8:25-9:10", "9:20-10:05", "10:20-11:05", "11:15-12:00", "12:10-12:55", "13:05-13:50", "14:00-14:45", "14:55-15:40", "15:50-16:35"}; - - String[] days = {"PO", "UT", "ST", "CT", "PA"}; - - Table t = new Table<>(labels); - - public byte download(String Jsessionid) - { - try - { - rozvrh.downloadRozvrh(Jsessionid); - - String[][] r = rozvrh.getRozvrh(); - - String[] s = new String[labels.length]; - - for(int i = 0; i < r.length; i++) - { - s[0] = days[i]; - for(int j = 1; j < r[i].length; j++) { s[j] = r[i][j]; } - - t.getTableModel().addRow(s); - } - t.addTo(rozvrhPanel); - - return 0; - }catch(UnknownHostException e) - { - return 127; - }catch(IOException e) - { - return 126; - } - } - - public Panel getPanel() - { - return rozvrhPanel; - } -} diff --git a/src/main/java/xyz/thastertyn/Window/WindowSwitchListener.java b/src/main/java/xyz/thastertyn/Window/WindowSwitchListener.java new file mode 100644 index 0000000..4a70d2c --- /dev/null +++ b/src/main/java/xyz/thastertyn/Window/WindowSwitchListener.java @@ -0,0 +1,123 @@ +package xyz.thastertyn.Window; + +import java.util.concurrent.atomic.AtomicBoolean; + +import com.googlecode.lanterna.TerminalPosition; +import com.googlecode.lanterna.TerminalSize; +import com.googlecode.lanterna.gui2.Label; +import com.googlecode.lanterna.gui2.Panel; +import com.googlecode.lanterna.gui2.Window; +import com.googlecode.lanterna.gui2.WindowBasedTextGUI; +import com.googlecode.lanterna.gui2.WindowListener; +import com.googlecode.lanterna.input.KeyStroke; +import com.googlecode.lanterna.input.KeyType; + +import xyz.thastertyn.Window.Content.JecnaContent; +import xyz.thastertyn.Window.Content.Rozvrh; +import xyz.thastertyn.Window.Content.Znamky; + +public class WindowSwitchListener implements WindowListener { + + WindowBasedTextGUI gui; + + private JecnaContent[] contents = {new Rozvrh(), new Znamky()}; + + private String JsessionId; + + Panel panel; + Label label; + + int current = 0; + + public WindowSwitchListener(Panel holder, String JsessionId) + { + panel = holder; + this.JsessionId = JsessionId; + this.label = label; + defaultPanel(); + } + + private void defaultPanel() + { + contents[0].download(JsessionId); + panel.removeAllComponents(); + panel.addComponent(contents[0].getPanel()); + //label.setText(contents[0].getLabel()); + } + + public void next() + { + if(current + 1 == contents.length) + { + current = 0; + }else{ + current++; + } + + if(!contents[current].hasStarted()) + { + contents[current].download(JsessionId); + } + + panel.removeAllComponents(); + panel.addComponent(contents[current].getPanel()); + + //label.setText(contents[current].getLabel()); + } + + public void previous() + { + if(current - 1 == -1) + { + current = contents.length - 1; + }else{ + current--; + } + + if(!contents[current].hasStarted()) + { + contents[current].download(JsessionId); + } + panel.removeAllComponents(); + panel.addComponent(contents[current].getPanel()); + + //label.setText(contents[current].getLabel()); + } + + + + @Override + public void onInput(Window basePane, KeyStroke keyStroke, AtomicBoolean deliverEvent) { + KeyType type = keyStroke.getKeyType(); + + switch(type) + { + case Tab: + if(!keyStroke.isShiftDown()) + { + next(); + }else{ + previous(); + } + break; + default: + break; + } + } + + @Override + public void onUnhandledInput(Window basePane, KeyStroke keyStroke, AtomicBoolean hasBeenHandled) { + // TODO Auto-generated method stub + } + + @Override + public void onResized(Window window, TerminalSize oldSize, TerminalSize newSize) { + window.invalidate(); + } + + @Override + public void onMoved(Window window, TerminalPosition oldPosition, TerminalPosition newPosition) { + // TODO Auto-generated method stub + } + +} diff --git a/target/classes/xyz/thastertyn/App.class b/target/classes/xyz/thastertyn/App.class index 8c05ee8..8fc5f3f 100644 Binary files a/target/classes/xyz/thastertyn/App.class and b/target/classes/xyz/thastertyn/App.class differ diff --git a/target/classes/xyz/thastertyn/Connection.class b/target/classes/xyz/thastertyn/Connection.class deleted file mode 100644 index 242c415..0000000 Binary files a/target/classes/xyz/thastertyn/Connection.class and /dev/null differ diff --git a/target/classes/xyz/thastertyn/Download.class b/target/classes/xyz/thastertyn/Download.class deleted file mode 100644 index 51b02c3..0000000 Binary files a/target/classes/xyz/thastertyn/Download.class and /dev/null differ diff --git a/target/classes/xyz/thastertyn/Jecna/Dochazka.class b/target/classes/xyz/thastertyn/Jecna/Dochazka.class index 5e44996..42f6c0e 100644 Binary files a/target/classes/xyz/thastertyn/Jecna/Dochazka.class and b/target/classes/xyz/thastertyn/Jecna/Dochazka.class differ diff --git a/target/classes/xyz/thastertyn/Jecna/Jidelna.class b/target/classes/xyz/thastertyn/Jecna/Jidelna.class new file mode 100644 index 0000000..b7f1869 Binary files /dev/null and b/target/classes/xyz/thastertyn/Jecna/Jidelna.class differ diff --git a/target/classes/xyz/thastertyn/Jecna/Login.class b/target/classes/xyz/thastertyn/Jecna/Login.class index f8ffa27..572fe36 100644 Binary files a/target/classes/xyz/thastertyn/Jecna/Login.class and b/target/classes/xyz/thastertyn/Jecna/Login.class differ diff --git a/target/classes/xyz/thastertyn/Jecna/Znamky.class b/target/classes/xyz/thastertyn/Jecna/Znamky.class index bc021b4..78c6ac4 100644 Binary files a/target/classes/xyz/thastertyn/Jecna/Znamky.class and b/target/classes/xyz/thastertyn/Jecna/Znamky.class differ diff --git a/target/classes/xyz/thastertyn/Predmet.class b/target/classes/xyz/thastertyn/Predmet.class deleted file mode 100644 index 8ffad90..0000000 Binary files a/target/classes/xyz/thastertyn/Predmet.class and /dev/null differ diff --git a/target/classes/xyz/thastertyn/RozvrhDownload.class b/target/classes/xyz/thastertyn/RozvrhDownload.class deleted file mode 100644 index 29eccbb..0000000 Binary files a/target/classes/xyz/thastertyn/RozvrhDownload.class and /dev/null differ diff --git a/target/classes/xyz/thastertyn/Window/Content/JecnaContent.class b/target/classes/xyz/thastertyn/Window/Content/JecnaContent.class new file mode 100644 index 0000000..4a1dc85 Binary files /dev/null and b/target/classes/xyz/thastertyn/Window/Content/JecnaContent.class differ diff --git a/target/classes/xyz/thastertyn/Window/Content/Jidelna.class b/target/classes/xyz/thastertyn/Window/Content/Jidelna.class new file mode 100644 index 0000000..2451488 Binary files /dev/null and b/target/classes/xyz/thastertyn/Window/Content/Jidelna.class differ diff --git a/target/classes/xyz/thastertyn/Window/Content/Rozvrh.class b/target/classes/xyz/thastertyn/Window/Content/Rozvrh.class new file mode 100644 index 0000000..dec4b33 Binary files /dev/null and b/target/classes/xyz/thastertyn/Window/Content/Rozvrh.class differ diff --git a/target/classes/xyz/thastertyn/Window/Content/Znamky.class b/target/classes/xyz/thastertyn/Window/Content/Znamky.class new file mode 100644 index 0000000..360f92f Binary files /dev/null and b/target/classes/xyz/thastertyn/Window/Content/Znamky.class differ diff --git a/target/classes/xyz/thastertyn/Window/Login.class b/target/classes/xyz/thastertyn/Window/Login.class index efdcebf..b20da03 100644 Binary files a/target/classes/xyz/thastertyn/Window/Login.class and b/target/classes/xyz/thastertyn/Window/Login.class differ diff --git a/target/classes/xyz/thastertyn/Window/LoginDialog.class b/target/classes/xyz/thastertyn/Window/LoginDialog.class deleted file mode 100644 index 926ccde..0000000 Binary files a/target/classes/xyz/thastertyn/Window/LoginDialog.class and /dev/null differ diff --git a/target/classes/xyz/thastertyn/Window/MainWindow.class b/target/classes/xyz/thastertyn/Window/MainWindow.class index 299a09c..c77f893 100644 Binary files a/target/classes/xyz/thastertyn/Window/MainWindow.class and b/target/classes/xyz/thastertyn/Window/MainWindow.class differ diff --git a/target/classes/xyz/thastertyn/Window/Rozvrh.class b/target/classes/xyz/thastertyn/Window/Rozvrh.class deleted file mode 100644 index 3a4dab8..0000000 Binary files a/target/classes/xyz/thastertyn/Window/Rozvrh.class and /dev/null differ diff --git a/target/classes/xyz/thastertyn/Window/WindowSwitchListener.class b/target/classes/xyz/thastertyn/Window/WindowSwitchListener.class new file mode 100644 index 0000000..a401765 Binary files /dev/null and b/target/classes/xyz/thastertyn/Window/WindowSwitchListener.class differ