Skip to content

Commit 32d8f6c

Browse files
committed
Add linux .deb builds, fix excel importing
1 parent 932b292 commit 32d8f6c

File tree

8 files changed

+216
-170
lines changed

8 files changed

+216
-170
lines changed

.github/workflows/build_release.yml

+32-2
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ on:
55
types: [ created ]
66

77
jobs:
8-
build_desktop:
8+
build_desktop_windows:
99
runs-on: windows-latest
1010

1111
steps:
1212
- uses: actions/checkout@v2
1313
- name: Set up Java
1414
uses: actions/setup-java@v1
1515
with:
16-
java-version: 17
16+
java-version: 20
1717

1818
- name: Generate runtime
1919
run: cd desktop && jlink --output ./runtime/ --no-man-pages --no-header-files --add-modules java.base,java.desktop,java.sql,jdk.charsets,java.net.http,jdk.crypto.ec,java.logging --compress=2
@@ -35,6 +35,36 @@ jobs:
3535
asset_name: TimeTable.exe
3636
tag: ${{ github.ref }}
3737

38+
build_desktop_linux:
39+
runs-on: ubuntu-latest
40+
41+
steps:
42+
- uses: actions/checkout@v2
43+
- name: Set up Java
44+
uses: actions/setup-java@v1
45+
with:
46+
java-version: 20
47+
48+
- name: Generate runtime
49+
run: cd desktop && jlink --output ./runtime/ --no-man-pages --no-header-files --add-modules java.base,java.desktop,java.sql,jdk.charsets,java.net.http,jdk.crypto.ec,java.logging --compress=2
50+
51+
- name: Copy libraries
52+
run: cd desktop && mvn dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=resources
53+
54+
- name: Create jar
55+
run: cd desktop && mvn package && mv target/TimeTable_Desktop-1.0.jar resources/TimeTable.jar
56+
57+
- name: Create installer
58+
run: cd desktop && jpackage --runtime-image runtime --input resources --main-class timetable.Main --main-jar TimeTable.jar --name TimeTable --vendor Degubi --description TimeTable --icon icon.png --linux-shortcut
59+
60+
- name: Upload binary to release
61+
uses: svenstaro/upload-release-action@v2
62+
with:
63+
repo_token: ${{ secrets.GITHUB_TOKEN }}
64+
file: desktop/timetable_1.0_amd64.deb
65+
asset_name: TimeTable.deb
66+
tag: ${{ github.ref }}
67+
3868
build_android:
3969
runs-on: windows-latest
4070

desktop/icon.png

832 Bytes
Loading

desktop/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
<artifactId>maven-compiler-plugin</artifactId>
4949
<version>3.8.1</version>
5050
<configuration>
51-
<release>17</release>
51+
<release>20</release>
5252
</configuration>
5353
</plugin>
5454
<plugin>

desktop/src/main/java/timetable/ClassButton.java

-18
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
import java.awt.Font;
66
import java.awt.event.*;
77
import java.time.*;
8-
import java.time.format.*;
98
import java.util.*;
109
import javax.swing.*;
11-
import org.apache.poi.ss.usermodel.*;
1210
import timetable.listeners.*;
1311

1412
public final class ClassButton extends MouseAdapter {
@@ -64,22 +62,6 @@ public static ClassButton fromEditorTable(JTable table, boolean unImportant) {
6462
(String) table.getValueAt(5, 1), unImportant);
6563
}
6664

67-
public static ClassButton fromTimetableExcel(Row classRow, DateTimeFormatter format) {
68-
var beginDate = LocalDateTime.parse(classRow.getCell(0).getStringCellValue(), format);
69-
var endDate = LocalDateTime.parse(classRow.getCell(1).getStringCellValue(), format);
70-
var summary = classRow.getCell(2).getStringCellValue();
71-
var codeBeginParamIndex = summary.indexOf('(');
72-
var code = summary.substring(codeBeginParamIndex + 1, summary.indexOf(')', codeBeginParamIndex));
73-
var lastCodeChar = Character.toUpperCase(code.charAt(code.length() - 1));
74-
75-
var day = Main.days[beginDate.getDayOfWeek().ordinal()];
76-
var className = summary.substring(0, codeBeginParamIndex - 1);
77-
var classType = code.contains("SZV") ? "Szabvál" : lastCodeChar == 'G' || lastCodeChar == 'L' ? "Gyakorlat" : "Előadás";
78-
var room = classRow.getCell(3).getStringCellValue();
79-
80-
return new ClassButton(day, className, classType, beginDate.toLocalTime(), endDate.toLocalTime(), room, false);
81-
}
82-
8365
@Override
8466
public void mousePressed(MouseEvent event) {
8567
if(event.getButton() == MouseEvent.BUTTON3) {

desktop/src/main/java/timetable/Main.java

+10-143
Original file line numberDiff line numberDiff line change
@@ -3,51 +3,40 @@
33
import java.awt.*;
44
import java.awt.Color;
55
import java.awt.TrayIcon.*;
6-
import java.awt.datatransfer.*;
7-
import java.awt.event.*;
8-
import java.io.*;
9-
import java.net.*;
10-
import java.net.http.*;
11-
import java.net.http.HttpResponse.*;
126
import java.time.*;
137
import java.time.format.*;
148
import java.util.*;
15-
import java.util.function.*;
169
import java.util.stream.*;
17-
import javax.imageio.*;
1810
import javax.swing.*;
1911
import javax.swing.border.*;
20-
import javax.swing.filechooser.*;
2112
import javax.swing.plaf.nimbus.*;
22-
import org.apache.poi.*;
23-
import org.apache.poi.ss.usermodel.*;
2413
import timetable.listeners.*;
2514

2615
public final class Main {
2716
private static final ArrayList<ClassButton> classButtons = new ArrayList<>();
28-
private static final JPanel mainPanel = new JPanel(new BorderLayout());
29-
private static final String BACKEND_URL = "http://localhost:8080/timetable";
30-
private static final HttpClient client = HttpClient.newHttpClient();
3117
private static final JLabel dateLabel = new JLabel("\0");
32-
private static final TrayIcon tray = new TrayIcon(Components.trayIcon.getScaledInstance(16, 16, Image.SCALE_SMOOTH), "Órarend");
3318
private static ClassButton lastActiveClass = null;
3419

3520
public static final String[] days = { "Hétfő", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat", "Vasárnap" };
3621
public static final JPanel classesPanel = new JPanel(null);
22+
public static final String BACKEND_URL = "http://localhost:8080/timetable";
3723

3824
public static void main(String[] args) throws Exception {
3925
UIManager.setLookAndFeel(new NimbusLookAndFeel());
4026
IntStream.range(0, 5).mapToObj(Main::newDayButton).forEach(classesPanel::add);
41-
updateClassesGui();
4227

4328
dateLabel.setBounds(350, 5, 300, 40);
4429
dateLabel.setFont(Components.bigFont);
4530
dateLabel.setHorizontalAlignment(SwingConstants.CENTER);
4631
dateLabel.setBorder(new EmptyBorder(15, 0, 20, 0));
32+
33+
var mainPanel = new JPanel(new BorderLayout());
4734
mainPanel.add(dateLabel, BorderLayout.PAGE_START);
4835
mainPanel.add(classesPanel, BorderLayout.CENTER);
4936

50-
var screenshotItem = Components.newMenuItem("Kép", "screencap.png", Main::exportToImage);
37+
updateClassesGui();
38+
39+
var screenshotItem = Components.newMenuItem("Kép", "screencap.png", TransferUtils::exportToImage);
5140
var frame = new JFrame("Órarend");
5241
frame.setBounds(0, 0, 1024, Math.min(768, Toolkit.getDefaultToolkit().getScreenSize().height - 50));
5342
frame.setLocationRelativeTo(null);
@@ -67,12 +56,13 @@ public static void main(String[] args) throws Exception {
6756
popMenu.add(Components.newMenuItem("Megnyitás", "open.png", SystemTrayListener::openFromTray));
6857
popMenu.addSeparator();
6958
popMenu.add(sleepMode);
70-
popMenu.add(Components.newSideMenu("Importálás", "import.png", Components.newMenuItem("Neptun Órarend Excel", "excel.png", Main::importFromExcel), Components.newMenuItem("Felhő", "db.png", Main::importFromCloud)));
71-
popMenu.add(Components.newSideMenu("Mentés", "export.png", screenshotItem, Components.newMenuItem("Felhő", "db.png", Main::exportToCloud)));
59+
popMenu.add(Components.newSideMenu("Importálás", "import.png", Components.newMenuItem("Neptun Órarend Excel", "excel.png", TransferUtils::importFromExcel), Components.newMenuItem("Felhő", "db.png", TransferUtils::importFromCloud)));
60+
popMenu.add(Components.newSideMenu("Mentés", "export.png", screenshotItem, Components.newMenuItem("Felhő", "db.png", TransferUtils::exportToCloud)));
7261
popMenu.add(Components.newMenuItem("Beállítások", "settings.png", PopupGuis::showSettingsGui));
7362
popMenu.addSeparator();
7463
popMenu.add(Components.newMenuItem("Bezárás", "exit.png", e -> System.exit(0)));
7564

65+
var tray = new TrayIcon(Components.trayIcon.getScaledInstance(16, 16, Image.SCALE_SMOOTH), "Órarend");
7666
tray.addMouseListener(new SystemTrayListener(popMenu));
7767
SystemTray.getSystemTray().add(tray);
7868
Runtime.getRuntime().addShutdownHook(new Thread(Settings::saveSettings));
@@ -127,129 +117,6 @@ private static JButton newDayButton(int dayIndex) {
127117
return topAdd;
128118
}
129119

130-
private static void exportToImage(@SuppressWarnings("unused") ActionEvent event) {
131-
Consumer<JDialog> exportFunction = dialog -> {
132-
var window = classesPanel.getTopLevelAncestor().getLocationOnScreen();
133-
var fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_kk_HH_ss")) + ".png";
134-
var exportFile = new File(fileName);
135-
136-
try {
137-
ImageIO.write(new Robot().createScreenCapture(new Rectangle(window.x + 20, window.y + 80, 990, 650)), "PNG", exportFile);
138-
Runtime.getRuntime().exec("explorer.exe /select," + exportFile);
139-
dialog.setVisible(false);
140-
} catch (HeadlessException | AWTException | IOException e1) {}
141-
};
142-
143-
showTransferDialog("Mentés folyamatban...", exportFunction);
144-
}
145-
146-
private static void exportToCloud(@SuppressWarnings("unused") ActionEvent event) {
147-
var userPwInput = JOptionPane.showInputDialog(mainPanel, "Írd be az órarend módosítás jelszavad!");
148-
149-
if(userPwInput != null) {
150-
Consumer<JDialog> exportFunction = dialog -> {
151-
var objectToSend = Map.of("classes", Settings.classes, "password", userPwInput);
152-
153-
var request = HttpRequest.newBuilder(URI.create(BACKEND_URL + (!Settings.cloudID.equals(Settings.NULL_CLOUD_ID) ? ("?id=" + Settings.cloudID) : "")))
154-
.POST(Settings.publisherOf(objectToSend));
155-
156-
var response = sendRequest(request, BodyHandlers.ofString());
157-
var responseStatusCode = response.statusCode();
158-
159-
dialog.setVisible(false);
160-
161-
if(responseStatusCode == 401) {
162-
JOptionPane.showMessageDialog(mainPanel, "Sikertelen mentés! Hibás jelszó!");
163-
}else if(responseStatusCode == 400) {
164-
Settings.cloudID = Settings.NULL_CLOUD_ID;
165-
JOptionPane.showMessageDialog(mainPanel, "Sikertelen mentés! Nem található ilyen azonosítójú órarend...\nAz eddigi felhő azonosító törlésre került!");
166-
}else if(responseStatusCode == 200) {
167-
var optionalReceivedCloudID = response.body();
168-
169-
if(optionalReceivedCloudID != null && !optionalReceivedCloudID.isBlank()) {
170-
Settings.cloudID = optionalReceivedCloudID;
171-
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(optionalReceivedCloudID), null);
172-
JOptionPane.showMessageDialog(mainPanel, "Új órarend létrehozva, azonosító: " + optionalReceivedCloudID + " (másolva vágólapra)");
173-
}else{
174-
JOptionPane.showMessageDialog(mainPanel, "Sikeres mentés!");
175-
}
176-
}
177-
};
178-
179-
showTransferDialog("Mentés folyamatban...", exportFunction);
180-
}
181-
}
182-
183-
private static void importFromExcel(@SuppressWarnings("unused") ActionEvent event) {
184-
var chooser = new JFileChooser(System.getProperty("user.home") + "/Desktop");
185-
chooser.setDialogTitle("Órarend Importálás Választó");
186-
chooser.setFileFilter(new FileNameExtensionFilter("Excel Files", "xls", "xlsx"));
187-
188-
if(chooser.showOpenDialog(classesPanel) == JFileChooser.APPROVE_OPTION) {
189-
Consumer<JDialog> importFunction = dialog -> {
190-
try(var book = WorkbookFactory.create(chooser.getSelectedFile().getAbsoluteFile())){
191-
var classesSheet = book.getSheetAt(0);
192-
var format = DateTimeFormatter.ofPattern("uuuu.MM.dd. [HH:][H:]mm:ss");
193-
194-
Settings.classes = StreamSupport.stream(classesSheet.spliterator(), false)
195-
.skip(1) // Header
196-
.map(row -> ClassButton.fromTimetableExcel(row, format))
197-
.collect(Collectors.toCollection(ArrayList::new));
198-
updateClassesGui();
199-
dialog.setVisible(false);
200-
}catch (FileNotFoundException e) {
201-
dialog.setVisible(false);
202-
JOptionPane.showMessageDialog(mainPanel, "Az excel fájl használatban van!", "Hiba", JOptionPane.ERROR_MESSAGE);
203-
} catch (EncryptedDocumentException | IOException e) {
204-
e.printStackTrace();
205-
}
206-
};
207-
208-
showTransferDialog("Importálás folyamatban...", importFunction);
209-
}
210-
}
211-
212-
private static void importFromCloud(@SuppressWarnings("unused") ActionEvent event) {
213-
var userIDInput = JOptionPane.showInputDialog(mainPanel, "Írd be az órarend azonosítót!");
214-
215-
if(userIDInput != null && !userIDInput.isBlank()) {
216-
Consumer<JDialog> importFunction = dialog -> {
217-
var responseClasses = sendRequest(HttpRequest.newBuilder(URI.create(BACKEND_URL + "?id=" + userIDInput)), Settings.of(Settings.CLASSES_TYPEREF)).body();
218-
219-
if(responseClasses != null) {
220-
Settings.classes = responseClasses;
221-
222-
dialog.setVisible(false);
223-
Settings.cloudID = userIDInput;
224-
updateClassesGui();
225-
}else{
226-
dialog.setVisible(false);
227-
JOptionPane.showMessageDialog(mainPanel, "Nem található ilyen azonsítójú órarend! :(", "Hiba", JOptionPane.ERROR_MESSAGE);
228-
}
229-
};
230-
231-
showTransferDialog("Importálás folyamatban...", importFunction);
232-
}
233-
}
234-
235-
private static<T> HttpResponse<T> sendRequest(HttpRequest.Builder request, BodyHandler<T> bodyHandler) {
236-
try {
237-
return client.send(request.header("Content-Type", "application/json").build(), bodyHandler);
238-
} catch (IOException | InterruptedException e) {
239-
e.printStackTrace();
240-
throw new IllegalStateException("Huh?");
241-
}
242-
}
243-
244-
245-
private static void showTransferDialog(String text, Consumer<JDialog> fun) {
246-
var jop = new JOptionPane(text, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null, new Object[0]);
247-
var dialog = jop.createDialog(mainPanel, "Órarend");
248-
249-
new Thread(() -> fun.accept(dialog)).start();
250-
dialog.setVisible(true);
251-
}
252-
253120
public static void updateClassesGui() {
254121
classButtons.forEach(k -> classesPanel.remove(k.button));
255122
classButtons.clear();
@@ -258,8 +125,8 @@ public static void updateClassesGui() {
258125
var today = days[nowDate.getDayOfWeek().ordinal()];
259126
var nowTime = nowDate.toLocalTime();
260127

261-
Components.handleNightMode(mainPanel, nowTime);
262128
Components.handleNightMode(classesPanel, nowTime);
129+
Components.handleNightMode(classesPanel.getParent(), nowTime);
263130
Components.handleNightMode(dateLabel, nowTime);
264131

265132
Settings.classes.stream()

0 commit comments

Comments
 (0)