Initial commit

This commit is contained in:
Thastertyn committed 2023-02-22 21:53:10 +01:00
commit a66d67676f
33 files changed
+793

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
/src/main/java/xyz/thastertyn/Jecna/Credentials.java
/target/classes/xyz/thastertyn/Jecna/Credentials.class
+3
View File
@@ -0,0 +1,3 @@
{
"java.configuration.updateBuildConfiguration": "interactive"
}
+96
View File
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xyz.thastertyn</groupId>
<artifactId>jecnak-tui</artifactId>
<version>1.0-SNAPSHOT</version>
<name>jecnak-tui</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.15.3</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>com.googlecode.lanterna</groupId>
<artifactId>lanterna</artifactId>
<version>3.2.0-alpha1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
+88
View File
@@ -0,0 +1,88 @@
package xyz.thastertyn;
import xyz.thastertyn.Jecna.*;
import xyz.thastertyn.Window.MainWindow;
/**
* Hello world!
*
*/
public class App {
public static void main(String[] args) {
//System.out.println("Hello World!");
//Login l = new Login();
//l.login(Credentials.user, Credentials.pass);
MainWindow window = new MainWindow();
window.run();
/*
try {
//#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")
.cookie("XSRF-TOKEN", XSRF_TOKEN)
.cookie("JSESSIONID", jidelnaJSESSIONID)
.get();
System.out.println(obedy.toString());
//#endregion
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e)
{
e.printStackTrace();
}*/
}
}
@@ -0,0 +1,15 @@
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;
}
}
@@ -0,0 +1,5 @@
package xyz.thastertyn;
public class Download {
}
@@ -0,0 +1,31 @@
package xyz.thastertyn.Jecna;
import java.io.IOException;
import java.util.HashMap;
import org.jsoup.nodes.Document;
import xyz.thastertyn.Connection;
import xyz.thastertyn.Tuple.Pair;
public class Dochazka {
private HashMap<String, Pair<String, String>> absence = new HashMap<>();
public byte downloadAbsence(String JSESSIOND)
{
Document absenceDoc;
try {
// absence-list
absenceDoc = Connection.getConnection()
.cookie("JSESSIOND", JSESSIOND)
.url("https://www.spsejecna.cz" + "/absence/passing-student")
.get();
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
}
@@ -0,0 +1,15 @@
package xyz.thastertyn.Jecna;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
public class Downloader {
public static Connection download(String url, String Jsessionid)
{
return Jsoup.connect(url)
.header("Connection", "keep-alive")
.cookie("role", "student")
.cookie("JSESSIONID", Jsessionid);
}
}
@@ -0,0 +1,102 @@
package xyz.thastertyn.Jecna;
import java.io.File;
import java.io.IOException;
import java.net.UnknownHostException;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.Connection.Method;
public class Login {
private String Jsessionid = null;
// Check for session expiration
private long start;
private long lastCheck;
/**
* Zkontroluje zda jiz neexistuji ulozene udaje na systemu
* @return <ul>
* <li> {@code true} soubor existuje a neni prazdny </li>
* <li> {@code false} neexistuje, nebo jsou prazdne </li>
* </ul>
*/
public boolean getCredentials()
{
File credentials = null;
if(System.getProperty("os.name").equals("Linux"))
{
credentials = new File("~/.local/share/jecnak/credentials.json");
}else if(System.getProperty("os.name").contains("Windows"))
{
credentials = new File(System.getenv("APPDATA\\jecnak\\"));
}
if(!credentials.exists() || credentials.length() == 0)
{
return false;
}
return true;
}
public String getJSESSIONID()
{
return Jsessionid;
}
public byte login(String user, String pass)
{
try {
//#region JSESSIONID
Connection.Response response = Jsoup.connect("https://www.spsejecna.cz")
.header("Connection", "keep-alive")
.method(Method.HEAD)
.execute();
Jsessionid = response.cookie("JSESSIONID");
//#endregion
//#region Token3
String token3 = Jsoup.connect("https://www.spsejecna.cz/user/role?role=student")
.header("Connection", "keep-alive")
.cookie("JSESSIONID", Jsessionid)
.get()
.select("input[name=token3]")
.attr("value");
//#endregion
//#region Login
Connection.Response 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
.header("Origin", "https://www.spsejecna.cz")
.header("Connection", "keep-alive")
.cookie("JSESSIONID", Jsessionid)
.cookie("role", "student")
.data("token3", token3)
.data("user", user)
.data("pass", pass)
.data("submit", "P%C5%99ihl%C3%A1sit+se")
.followRedirects(true)
.execute();
//#endregion
start = System.currentTimeMillis() / 1000L;
lastCheck = start;
return 0;
} catch(UnknownHostException e)
{
// Not connected to internet
return 127;
} catch(IOException e)
{
return 126;
}
}
}
@@ -0,0 +1,103 @@
package xyz.thastertyn.Jecna;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.HashSet;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
/**
* Jeden radek v rozvrhu
*/
public class Rozvrh {
private String[][] rozvrh = new String[5][10];
int pos = 0;
public void setPredmet(String pr, int d, int i)
{
rozvrh[d][i] = pr;
}
public String[][] getRozvrh()
{
return rozvrh;
}
@Override
public String toString()
{
String s = "";
for(String[] st : rozvrh)
{
s += ("| ");
for(String str : st)
{
s += String.format("%-5s", str) + " | ";
}
s += "\n";
}
return s;
}
/**
* Stahne rozvrh z www.spsejecna.cz a dale ho zpracuje do formy
* se kterou da pracovat
* @param Jsessionid ze stranek
* @return Status code
* <newline>
* <ul>
* <li> 0 - Operace probehla bez problemu</li>
* </ul>
* @throws UnknownHostException kdyz neni pripojeni k internetu
* @throws IOException ostatni exceptiony nejsou dulezite, tak jsou zahrnuty v jednom
*/
public void downloadRozvrh(final String Jsessionid) throws UnknownHostException, IOException
{
Document rozvrhDoc = Downloader.download("https://www.spsejecna.cz" + "/timetable/class", Jsessionid).get();
Elements rozvrhTable = rozvrhDoc.select("table.timetable").select("tr");
Elements[] rozvrhDny = new Elements[rozvrhTable.size()];
for(int i = 0; i < rozvrhTable.size(); i++)
{
rozvrhDny[i] = rozvrhTable.get(i).children();
}
for(int i = 1; i < 6; i++)
{
for(int j = 1; j < 11; j++)
{
String predmet = rozvrhDny[i].get(j).select("span.subject").text().replaceAll(" ", "/");
// Predmety jako CEL jsou trikrat, staci ale jen jednou
// V hashsetu se neopakuji prvky
HashSet<String> set = new HashSet<>();
String[] split = predmet.split("/");
for(String s : split)
{
set.add(s);
}
String pr = "";
if(set.size() > 1)
{
for(String s : set)
{
pr += s + "/";
}
pr = pr.substring(0, pr.length() - 1);
}else{
for(String s : set) { pr = s; break; }
}
rozvrh[i-1][j-1] = pr;
}
}
}
}
@@ -0,0 +1,111 @@
package xyz.thastertyn.Jecna;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import xyz.thastertyn.Tuple.Pair;
public class Znamky {
private boolean wasDownloaded;
// key (String) reprezentuje predmet, value (arraylist) znamky a pair znamku s jeji vahou
private HashMap<String, ArrayList<Pair<Integer, Double>>> grades = new HashMap<>();
public void addGrade(String subject, int grade, double weight)
{
grades.get(subject).add(new Pair<Integer,Double>(grade, weight));
}
public void addSubject(String subject)
{
grades.put(subject, new ArrayList<Pair<Integer, Double>>());
}
private double getAverage(ArrayList<Pair<Integer, Double>> a)
{
try{
int divident = 0;
int divisor = 0;
for(Pair<Integer, Double> p : a)
{
divident += p.getValue0() * p.getValue1();
divisor += p.getValue1();
}
return (double) divident / divisor;
}catch(ArithmeticException e)
{
return 0;
}
}
public byte downloadZnamky(final String Jsessionid)
{
wasDownloaded = true;
Document znamkyDoc = null;
try {
znamkyDoc = Downloader.download("https://www.spsejecna.cz" + "/score/student", Jsessionid).get();
} catch (IOException e) {
e.printStackTrace();
return 127;
}
Elements rows = znamkyDoc.select("table.score").select("tr");
Elements[] rows_split = new Elements[rows.size()];
for (int i = 0; i < rows.size(); i++)
{
rows_split[i] = rows.get(i).children();
}
for(int i = 1; i < rows_split.length; i++)
{
String predmet = rows_split[i].get(0).text();
addSubject(predmet);
for(Element e : rows_split[i].get(1).select("a.score"))
{
int znamka = Integer.parseInt(e.select("span.value").text());
// Mala znamka se bude pocitat jako polovicni vaha
if(e.hasClass("scoreSmall"))
{
addGrade(predmet, znamka, 0.5);
}else{
addGrade(predmet, znamka, 1);
}
}
}
return 0;
}
@Override
public String toString()
{
if(wasDownloaded)
{
String s = "";
for(Map.Entry<String, ArrayList<Pair<Integer, Double>>> entry : grades.entrySet())
{
double prumer = getAverage(entry.getValue());
double p = (double) Math.round(prumer * 100) / 100;
s += entry.getKey() + " | " + entry.getValue().toString() + " { " + p + " }\n";
}
return s;
}else{
return "Nothing was downloaded";
}
}
}
@@ -0,0 +1,8 @@
package xyz.thastertyn;
import java.util.ArrayList;
public class Predmet {
}
@@ -0,0 +1,5 @@
package xyz.thastertyn;
public class RozvrhDownload {
}
@@ -0,0 +1,53 @@
package xyz.thastertyn.Tuple;
/**
* Ekvitalent Tuplu, ktery neni zabudovan v jave
*/
public class Pair<T1, T2> {
private T1 value0;
private T2 value1;
public Pair(T1 value0, T2 value1)
{
this.value0 = value0;
this.value1 = value1;
}
public Pair()
{
}
public void put(T1 value0, T2 value1)
{
this.value0 = value0;
this.value1 = value1;
}
public T1 getValue0()
{
return value0;
}
public T2 getValue1()
{
return value1;
}
public void setValue0(T1 value0)
{
this.value0 = value0;
}
public void setValue1(T2 value1)
{
this.value1 = value1;
}
@Override
public String toString()
{
return "[" + value0 + ", " + value1 + "]";
}
}
@@ -0,0 +1,74 @@
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.DefaultWindowManager;
import com.googlecode.lanterna.gui2.Direction;
import com.googlecode.lanterna.gui2.EmptySpace;
import com.googlecode.lanterna.gui2.LinearLayout;
import com.googlecode.lanterna.gui2.MultiWindowTextGUI;
import com.googlecode.lanterna.gui2.Panel;
import com.googlecode.lanterna.gui2.Separator;
import com.googlecode.lanterna.gui2.Window;
import com.googlecode.lanterna.screen.Screen;
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();
public void run()
{
Terminal terminal = null;
try {
// Setup terminal and screen layers
terminal = new DefaultTerminalFactory().createTerminal();
Screen screen = new TerminalScreen(terminal);
screen.startScreen();
// Create panel to hold components
final Panel mainPanel = new Panel();
mainPanel.setLayoutManager(new LinearLayout(Direction.HORIZONTAL));
// 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);
Login l = new Login();
l.login(Credentials.user, Credentials.pass);
Rozvrh r = new Rozvrh();
r.download(l.getJSESSIONID());
content.addComponent(r.getPanel());
// Create gui and start gui
final MultiWindowTextGUI gui = new MultiWindowTextGUI(screen, new DefaultWindowManager(), new EmptySpace(TextColor.ANSI.BLACK_BRIGHT));
/*KeyStroke k = terminal.readInput();
if(k.equals(KeyStroke.fromString("<up>")))
{
window.close();
}*/
gui.addWindowAndWait(window);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,62 @@
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<String> 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;
}
}
+20
View File
@@ -0,0 +1,20 @@
package xyz.thastertyn;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
/**
* Unit test for simple App.
*/
public class AppTest
{
/**
* Rigorous Test :-)
*/
@Test
public void shouldAnswerWithTrue()
{
assertTrue( true );
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.