initial commit
This commit is contained in:
commit
a0f1e13f93
7 changed files with 370 additions and 0 deletions
26
.gitignore
vendored
Normal file
26
.gitignore
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# ---> Java
|
||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
|
||||||
|
# Mobile Tools for Java (J2ME)
|
||||||
|
.mtj.tmp/
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
replay_pid*
|
||||||
|
|
27
README.md
Normal file
27
README.md
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# Getting started
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
- FirstSpirit installation
|
||||||
|
- Compiled FSHook project (FSHook/bin/uploadPlugin.jar exists)
|
||||||
|
- OpenJDK11 (On Windows this gets installed together with FS `C:/Users/<User>/.firstspirit/FSLauncher/jre/11.0.11/jre-win/jdk-11.0.11+9-jre/bin/java.exe`)
|
||||||
|
|
||||||
|
## Paths
|
||||||
|
- `<java>` point to your (or FSs) OpenJDK11 installation
|
||||||
|
- `<aspectjweaver.jar>` can be found in `FSHook/tool`
|
||||||
|
- `<classpath>` points to
|
||||||
|
- `bin/` of this project,
|
||||||
|
- `FSHook/bin/*` and `FSHook/lib/aspectjrt.jar` of FSHook
|
||||||
|
- `.firstspirit/FSLauncher/jar/*`, `.firstspirit_<version>/jars/*` of the FS installation. (usually located in $HOME) - The seperator is `:` on Linux and `;` on Windows.
|
||||||
|
|
||||||
|
## Build this
|
||||||
|
I.e. with vs-code java extension.
|
||||||
|
Set classpath and add `res/` to source directories
|
||||||
|
|
||||||
|
## Launch this
|
||||||
|
1) Be in the TU-Network or connected via VPN.
|
||||||
|
2) Launch
|
||||||
|
``` <java> -cp <classpath> -javaaagent:<aspectjweaver.jar> com.kallendorf.Main```
|
||||||
|
3) Log in
|
||||||
|
4) Click on the scroll-icon in the toolbar.
|
||||||
|
This will link all protocolls of this year.
|
||||||
|
|
BIN
resources/Scroll.png
Normal file
BIN
resources/Scroll.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
21
src/com/kallendorf/fsplugin/Main.java
Normal file
21
src/com/kallendorf/fsplugin/Main.java
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package com.kallendorf.fsplugin;
|
||||||
|
|
||||||
|
import com.kallendorf.fsplugin.fsprotokolle.FSProtokollPlugin;
|
||||||
|
import de.espirit.firstspirit.client.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.kallendorf.fshook.CustomLoader;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Plugin p = new FSProtokollPlugin();
|
||||||
|
Set<Plugin> pSet = new HashSet<>();
|
||||||
|
pSet.add(p);
|
||||||
|
String[] fsargs = { "--system-properties",
|
||||||
|
"FS-eJydlVtv2jAYhv/K/gAmPuTgRb6IWqpF4yABVaepEnITF9KGJLINhV3sty8pMPF53UYrbnjs9/1OtiEZDhc3g2R+Ox3MxKMsjYqvhulgPF98mYwGi+t0Kn720WOhjTVNoQu78BGZEuJxV7dI0m8Xa4fp+PZy9Si5ulg7mwyTaTq7WH+Xjq8nd//QT6aDBfb8iAmrN+rImFH/nInHyGl8h4X2AwTECwAHjEIOyTlTTCLADIN41Och4CDkgEPPAxxFAWQO43EM43EK9dyH9fAA1Ms8xiEHIeTQhxxBbjuGzGB8HHiQI2cf9sOIRx2OIGPP4QAycfaJE5848eGFYCRwOHT0oZMPnh8jkaPnTj1uvxz6qdM/xQyy0x8lxGEnHnXiOedDIyeeUx/lcP4M3k/GnPraBIB953x85zx8eqxnPlvgEHftHd5jx5FHaXjOPvbxOYc0ZL/txMOcHLNl9brRypiiroQXqyrT+8Z2QOJVbazQKpfP3QKym14u9dpYmVuUq/hJbmVvu+5JvTTiU68n87xXN6oy96LbQg/SqP7rt1JWy3uRDIe92/E4GQ2u31DnyjzbujkY5ItFaqsq+x7XDpmXolqippSPXfIi+7Db7Cu7esutdk2tLejQbCpkVLZpf1T3SGbdqP7vPGVup49k05QKqbbny31d0o8YkFmpsnyf7XUuH7C8a5R/uq18KBUwxmWdyVKJ9u6V9bKoRFYW7R05ALJF9qyswKzeKcwLKvfV8rS1b5QYJek4XstdsS5+qOPTWNe5ErPJ1dfBPO6qEdiLorjR9ZPKbJqLKAwizoNYq2VhrN63/6Bt/pv2lGu9n54WW32jtC2UiY3S21LZ73WlRD/umum6IznKaX54bxtdipW1jfnc7//9bW2MehUd6vwF9UPXOA==" };
|
||||||
|
CustomLoader.launchFS(fsargs, pSet);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.kallendorf.fsplugin.fsprotokolle;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class FSProtokollHelper {
|
||||||
|
final static String MATHEBAU_PROTKOLLE = "https://mathebau.de/protokolle/";
|
||||||
|
|
||||||
|
public static String[] getProtokollNames() {
|
||||||
|
String content = null;
|
||||||
|
URLConnection connection = null;
|
||||||
|
try {
|
||||||
|
connection = new URL(MATHEBAU_PROTKOLLE).openConnection();
|
||||||
|
Scanner scanner = new Scanner(connection.getInputStream());
|
||||||
|
scanner.useDelimiter("\\Z");
|
||||||
|
content = scanner.next();
|
||||||
|
scanner.close();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] protokolle = Arrays.stream(content.split(System.lineSeparator()))
|
||||||
|
.filter(l -> l.startsWith("<a href=\"fs-protokoll-"))
|
||||||
|
.map(l -> l.split("\"")[1])
|
||||||
|
.toArray(String[]::new);
|
||||||
|
return protokolle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getProtokollNamesCurrent() {
|
||||||
|
int year = Calendar.getInstance().get(Calendar.YEAR);
|
||||||
|
String yearString = String.valueOf(year);
|
||||||
|
String[] allProtokolls = getProtokollNames();
|
||||||
|
String[] currentProtokolls = Arrays.stream(allProtokolls)
|
||||||
|
.filter(t -> t.split("-")[2].equals(yearString))
|
||||||
|
.toArray(String[]::new);
|
||||||
|
return currentProtokolls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] parseDate(String protokollTitle) {
|
||||||
|
// fs-protokoll-2020-12-16_A-Teil_en.pdf
|
||||||
|
String[] parts = protokollTitle.split("-");
|
||||||
|
return new int[] { Integer.parseInt(parts[2]), Integer.parseInt(parts[3]), Integer.parseInt(parts[4]) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String verboseTitleString(String protokollTitle) {
|
||||||
|
int[] dateParts = parseDate(protokollTitle);
|
||||||
|
return String.format("Protokoll der Sitzung vom %2d.%2d.%4d", dateParts[2], dateParts[1], dateParts[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDownloadLink(String protokollTitle) {
|
||||||
|
return MATHEBAU_PROTKOLLE + protokollTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,202 @@
|
||||||
|
package com.kallendorf.fsplugin.fsprotokolle;
|
||||||
|
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import de.espirit.common.event.ValueChangeEvent;
|
||||||
|
import de.espirit.common.event.ValueChangeListener;
|
||||||
|
import de.espirit.firstspirit.access.Language;
|
||||||
|
import de.espirit.firstspirit.access.editor.DomEditorValue;
|
||||||
|
import de.espirit.firstspirit.access.editor.NumberEditorValue;
|
||||||
|
import de.espirit.firstspirit.access.editor.TextEditorValue;
|
||||||
|
import de.espirit.firstspirit.access.editor.ToggleEditorValue;
|
||||||
|
import de.espirit.firstspirit.access.editor.value.DefaultDomNode;
|
||||||
|
import de.espirit.firstspirit.access.editor.value.DomElement;
|
||||||
|
import de.espirit.firstspirit.access.editor.value.DomNode;
|
||||||
|
import de.espirit.firstspirit.access.editor.value.InvalidValueException;
|
||||||
|
import de.espirit.firstspirit.access.store.ElementDeletedException;
|
||||||
|
import de.espirit.firstspirit.access.store.ElementMovedException;
|
||||||
|
import de.espirit.firstspirit.access.store.LockException;
|
||||||
|
import de.espirit.firstspirit.access.store.Store;
|
||||||
|
import de.espirit.firstspirit.access.store.StoreElement;
|
||||||
|
import de.espirit.firstspirit.access.store.Store.Type;
|
||||||
|
import de.espirit.firstspirit.access.store.pagestore.Body;
|
||||||
|
import de.espirit.firstspirit.access.store.pagestore.Page;
|
||||||
|
import de.espirit.firstspirit.access.store.pagestore.Section;
|
||||||
|
import de.espirit.firstspirit.access.store.templatestore.FormatTemplate;
|
||||||
|
import de.espirit.firstspirit.access.store.templatestore.FormatTemplates;
|
||||||
|
import de.espirit.firstspirit.access.store.templatestore.LinkTemplate;
|
||||||
|
import de.espirit.firstspirit.access.store.templatestore.LinkTemplates;
|
||||||
|
import de.espirit.firstspirit.access.store.templatestore.SectionTemplate;
|
||||||
|
import de.espirit.firstspirit.access.store.templatestore.SectionTemplates;
|
||||||
|
import de.espirit.firstspirit.access.store.templatestore.TemplateStoreRoot;
|
||||||
|
import de.espirit.firstspirit.access.store.templatestore.gom.GomText;
|
||||||
|
import de.espirit.firstspirit.access.store.templatestore.gom.GomToggle;
|
||||||
|
import de.espirit.firstspirit.agency.LanguageAgent;
|
||||||
|
import de.espirit.firstspirit.agency.OperationAgent;
|
||||||
|
import de.espirit.firstspirit.agency.StoreAgent;
|
||||||
|
import de.espirit.firstspirit.client.access.editor.EditorValueChangedEvent;
|
||||||
|
import de.espirit.firstspirit.client.access.editor.EditorValueListener;
|
||||||
|
import de.espirit.firstspirit.client.access.editor.ReferenceTransformationAgent;
|
||||||
|
import de.espirit.firstspirit.client.access.editor.ValueEngineer;
|
||||||
|
import de.espirit.firstspirit.client.access.editor.ValueEngineerFactory;
|
||||||
|
import de.espirit.firstspirit.client.access.link.LinkImpl;
|
||||||
|
import de.espirit.firstspirit.client.plugin.toolbar.ExecutableToolbarItem;
|
||||||
|
import de.espirit.firstspirit.client.plugin.toolbar.ToolbarContext;
|
||||||
|
import de.espirit.firstspirit.forms.FormData;
|
||||||
|
import de.espirit.firstspirit.forms.FormField;
|
||||||
|
import de.espirit.firstspirit.store.access.DataBuilder;
|
||||||
|
import de.espirit.firstspirit.store.operations.ReleaseOperation;
|
||||||
|
import de.espirit.firstspirit.store.operations.SaveOperation;
|
||||||
|
|
||||||
|
public class FSProtokollMenuItem implements ExecutableToolbarItem {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @wbp.parser.entryPoint
|
||||||
|
*/
|
||||||
|
public FSProtokollMenuItem() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel(@NotNull final ToolbarContext context) {
|
||||||
|
return "PermissionViewPlugin";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Icon getIcon(@NotNull final ToolbarContext context) {
|
||||||
|
// Credites to FontAwesome CC BY SA 4.0
|
||||||
|
InputStream is = FSProtokollPlugin.class.getResourceAsStream("/Scroll.png");
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new ImageIcon(ImageIO.read(is).getScaledInstance(30, 24, Image.SCALE_SMOOTH));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Icon getPressedIcon(@NotNull final ToolbarContext context) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Icon getRollOverIcon(@NotNull final ToolbarContext context) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVisible(@NotNull final ToolbarContext context) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled(@NotNull final ToolbarContext context) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute(@NotNull final ToolbarContext context) {
|
||||||
|
// get the applicationservice from servicesBroker
|
||||||
|
StoreAgent storeAgent = context.requestSpecialist(StoreAgent.TYPE);
|
||||||
|
Store pageStore = storeAgent.getStore(Type.PAGESTORE);
|
||||||
|
|
||||||
|
OperationAgent operationAgent = context.requireSpecialist(OperationAgent.TYPE);
|
||||||
|
SaveOperation saveOperation = operationAgent.getOperation(SaveOperation.TYPE);
|
||||||
|
saveOperation.setRecursionEnabled(true);
|
||||||
|
ReleaseOperation releaseOperation = operationAgent.getOperation(ReleaseOperation.TYPE);
|
||||||
|
releaseOperation.recursive(true);
|
||||||
|
releaseOperation.withComment("FSProtokoll Plugin on Tour");
|
||||||
|
|
||||||
|
int year = Calendar.getInstance().get(Calendar.YEAR);
|
||||||
|
Language language = context.requestSpecialist(LanguageAgent.TYPE).getMasterLanguage();
|
||||||
|
|
||||||
|
Page protokollseite = (Page) getChildByName(pageStore, "fsmathe", "fachschaft_responsiv",
|
||||||
|
"fachschaftsarbeit_1", "downloads___links_1", "fs_protokolle_1");
|
||||||
|
Body pageBody = (Body) getChildByName(protokollseite, "zentral");
|
||||||
|
|
||||||
|
try {
|
||||||
|
protokollseite.setLock(true, true);
|
||||||
|
|
||||||
|
// retrive Templates
|
||||||
|
final TemplateStoreRoot templateStore = (TemplateStoreRoot) context.requireSpecialist(StoreAgent.TYPE)
|
||||||
|
.getStore(Store.Type.TEMPLATESTORE);
|
||||||
|
|
||||||
|
final SectionTemplates sectionTemplates = templateStore.getSectionTemplates();
|
||||||
|
final SectionTemplate sectionTemplate = sectionTemplates.getTemplate("text@tud_vorlagen");
|
||||||
|
|
||||||
|
final FormatTemplates formatTemplates = templateStore.getFormatTemplates();
|
||||||
|
final FormatTemplate paragraphTemplate = formatTemplates.getFormatTemplate("p");
|
||||||
|
|
||||||
|
final LinkTemplates linkTemplates = templateStore.getLinkTemplates();
|
||||||
|
final LinkTemplate linkTemplate = linkTemplates.getTemplate("externerlink");
|
||||||
|
|
||||||
|
try {
|
||||||
|
final StoreElement oldSection = getChildByName(pageBody, "protokoll_" + year);
|
||||||
|
oldSection.setLock(true);
|
||||||
|
oldSection.delete();
|
||||||
|
pageBody.removeChild(oldSection);
|
||||||
|
pageBody.refresh();
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
// Nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
Section<SectionTemplate> section = pageBody.createSection("protokoll_" + year, sectionTemplate);
|
||||||
|
pageBody.moveChild(section, 1);
|
||||||
|
section.setDisplayName(language, String.valueOf(year));
|
||||||
|
section.includeInOutput(language);
|
||||||
|
FormData sectionFormData = section.getFormData();
|
||||||
|
|
||||||
|
sectionFormData.get(language, "st_ueberschrift").set(String.valueOf(year));
|
||||||
|
sectionFormData.get(language, "st_toggle").set(true);
|
||||||
|
sectionFormData.get(language, "st_ueberschrift_zeichen").set(4);
|
||||||
|
sectionFormData.get(language, "st_ueberschrift_ebene").set(2);
|
||||||
|
|
||||||
|
FormField<DomElement> editor = (FormField<DomElement>) sectionFormData.get(language, "st_text");
|
||||||
|
|
||||||
|
// get the dom element and rootNode of the editor value
|
||||||
|
final DomElement domElement = editor.get();
|
||||||
|
final DefaultDomNode rootDomNode = domElement.getRoot();
|
||||||
|
for (DomNode n : rootDomNode.getChildren()) {
|
||||||
|
rootDomNode.removeChild(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// append a paragraph by using the paragraphTemplate
|
||||||
|
String[] protokolle = FSProtokollHelper.getProtokollNamesCurrent();
|
||||||
|
for (int i = protokolle.length - 1; i >= 0; i--) {
|
||||||
|
String protokollName = protokolle[i];
|
||||||
|
final DefaultDomNode paragraph = (DefaultDomNode) rootDomNode.appendChild(paragraphTemplate);
|
||||||
|
final LinkImpl link = (LinkImpl) linkTemplate.createLink(language);
|
||||||
|
link.setAttribute("ref", FSProtokollHelper.getDownloadLink(protokollName));
|
||||||
|
link.setText(protokollName);
|
||||||
|
paragraph.appendChild(link);
|
||||||
|
}
|
||||||
|
editor.set(domElement);
|
||||||
|
section.setFormData(sectionFormData);
|
||||||
|
|
||||||
|
saveOperation.setRecursionEnabled(true);
|
||||||
|
saveOperation.setComment("FSProtokoll Plugin has fired.");
|
||||||
|
saveOperation.perform(protokollseite);
|
||||||
|
protokollseite.setLock(false, true);
|
||||||
|
|
||||||
|
releaseOperation.perform(protokollseite);
|
||||||
|
|
||||||
|
System.out.println("Ende");
|
||||||
|
} catch (InvalidValueException | LockException | ElementDeletedException | ElementMovedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private StoreElement getChildByName(StoreElement rootNode, String... path) {
|
||||||
|
StoreElement node = rootNode;
|
||||||
|
for (String name : path) {
|
||||||
|
node = node.getChildren().toList().stream().filter(s -> s.getName().equals(name)).findFirst().get();
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.kallendorf.fsplugin.fsprotokolle;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import de.espirit.firstspirit.access.BaseContext;
|
||||||
|
import de.espirit.firstspirit.client.plugin.JavaClientEditorialToolbarItemsPlugin;
|
||||||
|
import de.espirit.firstspirit.client.plugin.toolbar.JavaClientToolbarItem;
|
||||||
|
|
||||||
|
public class FSProtokollPlugin implements JavaClientEditorialToolbarItemsPlugin{
|
||||||
|
// Field definitions for objects that are required during the lifetime of a class instance.
|
||||||
|
BaseContext _context;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp(@NotNull final BaseContext context) {
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tearDown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<? extends JavaClientToolbarItem> getItems() {
|
||||||
|
// Create and return an array list that includes individual button item objects.
|
||||||
|
return (Collection<? extends JavaClientToolbarItem>) Arrays.asList(
|
||||||
|
new FSProtokollMenuItem()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue