Compare commits

...

92 Commits

Author SHA1 Message Date
Verena Schulz b3fa931c4e Edited documentation 2026-01-21 18:32:55 +01:00
eric.minning c201574fd9 Merge branch 'feature/ui-test' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into feature/ui-test 2026-01-21 18:30:57 +01:00
eric.minning 14c89bfb17 Fixes in language.js and script.js 2026-01-21 18:30:47 +01:00
Verena Schulz b56b7e04d6 Css fixes 2026-01-21 18:14:41 +01:00
Verena Schulz 56224d9c14 Fixed main h1 2026-01-21 17:59:18 +01:00
Verena Schulz ccc1002a59 Fixed helppage bug 2026-01-21 17:41:17 +01:00
Verena Schulz b7f4ae93ce Fixed burger menu 2026-01-21 17:28:46 +01:00
Minning, Eric 2380dc6b3d Merge branch 'feature/help_page' into 'feature/ui-test'
Feature/help page

See merge request proj-wise2526-video2document/video2document!107
2026-01-21 17:12:13 +01:00
eric.minning e9be536f29 Help page changeLanguage integration and visibility regulation 2026-01-21 15:29:19 +01:00
santa 31487d9c36 document example pictures included, icon paths corrected 2026-01-21 15:28:28 +01:00
eric.minning 2627e5f44e Integrated the help page into the base files and added more exception handling 2026-01-21 14:01:34 +01:00
santa f0b5002c34 language czechia and russia implemented 2026-01-21 13:46:20 +01:00
Minning, Eric bb0ad2b621 Merge branch 'develop' into 'feature/ui-test'
Develop

See merge request proj-wise2526-video2document/video2document!105
2026-01-21 13:39:21 +01:00
Minning, Eric feca906ab6 Merge branch 'feature/help_page' into 'develop'
id for all help page elements and language translations for the help page created

See merge request proj-wise2526-video2document/video2document!104
2026-01-21 13:35:16 +01:00
santa 3d5265cdda id for all help page elements and language transllations for the help page created 2026-01-21 13:18:27 +01:00
eric.minning 73ed48d8c5 Expanded error catching and comments 2026-01-21 12:53:19 +01:00
eric.minning 192ef447a6 Added Comments 2026-01-21 12:19:35 +01:00
Spanier, Pit 2f5737d9bc Merge branch 'feature/documentation_2' into 'develop'
Added Documentation for the API Key authentication system

See merge request proj-wise2526-video2document/video2document!103
2026-01-21 11:42:24 +01:00
emily 55df227599 Added Documentation for the API Key authentication system 2026-01-21 11:04:43 +01:00
Spanier, Pit 5c7b1ac5e9 Merge branch 'feature/ui-test' into 'develop'
Removed the "confirm alert" in the delete costume document function. It made...

See merge request proj-wise2526-video2document/video2document!102
2026-01-21 10:55:15 +01:00
Verena Schulz c202d3960b Small changes to p-menu1 2026-01-20 17:57:03 +01:00
Verena Schulz ec64564a51 Merge branch 'feature/ui-test' of gitlab.rlp.net:proj-wise2526-video2document/video2document into feature/ui-test 2026-01-20 17:55:09 +01:00
Verena Schulz c1efe77ec1 Added UI documentation to documentation.md 2026-01-20 17:54:37 +01:00
eric.minning f706dcaf79 Removed the "confirm alert" in the delete costume document function. It made the textarea unklickable 2026-01-20 16:46:32 +01:00
eric.minning dacfa2094c Fixed a problem with the costum document text display 2026-01-19 18:31:06 +01:00
eric.minning 49e2724ad3 Removed unused files 2026-01-19 15:30:56 +01:00
eric.minning c43ec93894 Fixed and expanded the change language function. fixed custome document creation visibility 2026-01-19 15:22:32 +01:00
Minning, Eric 5ab29e8423 Merge branch 'develop' into 'feature/ui-test'
Develop

See merge request proj-wise2526-video2document/video2document!101
2026-01-19 14:44:23 +01:00
Hughes, Mike 36c0fde0b1 Merge branch 'fix/document-output-type' into 'develop'
Update output type option from '.word' to '.docx' in index.html

See merge request proj-wise2526-video2document/video2document!100
2026-01-18 19:44:41 +01:00
MikeHughes-BIN 4ca0d46aa9 Update output type option from '.word' to '.docx' in index.html 2026-01-18 19:41:40 +01:00
Hughes, Mike e88e0c45c0 Merge branch 'fix/redundant-function-call' into 'develop'
Remove duplicated file_download event handler from ipcMain

See merge request proj-wise2526-video2document/video2document!98
2026-01-18 19:28:36 +01:00
Hughes, Mike 8341861ae2 Merge branch 'fix/language' into 'develop'
Fix/language

See merge request proj-wise2526-video2document/video2document!99
2026-01-18 19:27:56 +01:00
MikeHughes-BIN b6276b005e Removed Parakeet again as it requires PyTorch which is too large for this project 2026-01-18 19:13:18 +01:00
MikeHughes-BIN 8f2024df14 Refactor HTML structure for improved readability and maintainability 2026-01-18 19:12:04 +01:00
MikeHughes-BIN 0f548b3012 Add function to send speaker packages and handle errors 2026-01-18 19:05:55 +01:00
MikeHughes-BIN 17479be27a Remove duplicated file_download event handler from ipcMain 2026-01-18 18:18:36 +01:00
Hughes, Mike 7fbf0c59d1 Merge branch 'feature/ui-test' into 'develop'
Feature/ui test

See merge request proj-wise2526-video2document/video2document!96
2026-01-18 18:02:35 +01:00
Hughes, Mike ef20a08d9f Merge branch 'fix/speaker-selection' into 'develop'
Speakers that have been renamed will stay in the selection as requested by Oliver

See merge request proj-wise2526-video2document/video2document!97
2026-01-18 18:00:53 +01:00
MikeHughes-BIN 9a3f84efc8 Speakers that have been renamed will stay in the selection as requested by Oliver 2026-01-18 17:57:18 +01:00
Hughes, Mike 6813b45c80 Merge branch 'develop' into 'feature/ui-test'
# Conflicts:
#   main.js
2026-01-18 17:38:36 +01:00
MikeHughes-BIN 773e8b471c Remove notification for successful file download in ipcMain handler 2026-01-18 17:37:47 +01:00
MikeHughes-BIN 013c9b5f2c Refactor file download handling to improve error management and user notifications 2026-01-18 17:32:29 +01:00
MikeHughes-BIN 18e791d56e Refactor code formatting and improve error handling in htmlDocumentConverter 2026-01-18 17:28:41 +01:00
MikeHughes-BIN 1ed386fcf4 Enhance file download handling and format validation in htmlDocumentConverter 2026-01-18 17:02:29 +01:00
MikeHughes-BIN c98d7761b2 Refactor UI elements for step selection and speaker management; improve styling and accessibility 2026-01-18 16:55:42 +01:00
Hughes, Mike d09b75a6cd Merge branch 'feature/ui-test' into 'develop'
Feature/ui test

See merge request proj-wise2526-video2document/video2document!95
2026-01-17 14:35:38 +01:00
Verena Schulz 0427056f65 Small changes 2026-01-17 00:11:57 +01:00
Verena Schulz 8076fe92f5 Integrated customDocBtn better with css into the menu 2026-01-17 00:11:37 +01:00
Verena Schulz c2e6c4a186 Style changes for custom document css 2026-01-16 23:59:30 +01:00
Verena Schulz 826381d858 Added hover effects for other document types 2026-01-16 23:54:31 +01:00
Hughes, Mike 4ac59e7597 Merge branch 'feature/ui-test' into 'develop'
Feature/ui test

See merge request proj-wise2526-video2document/video2document!94
2026-01-15 17:19:58 +01:00
eric.minning b5d374498f Merge branch 'feature/ui-test' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into feature/ui-test 2026-01-15 17:11:42 +01:00
eric.minning 567ec0aa1b The language key for the document language gets send to the main now 2026-01-15 17:11:32 +01:00
Spanier, Pit 906929169e Merge branch 'fix/main-file-safe' into 'develop'
fixed pipeline

See merge request proj-wise2526-video2document/video2document!93
2026-01-15 16:58:44 +01:00
emily df5ac8913d fixed pipeline 2026-01-15 16:54:09 +01:00
Spanier, Pit 30ef4d4738 Merge branch 'fix/main-file-safe' into 'develop'
Enhance module retrieval by categorizing AI and transcription modules

See merge request proj-wise2526-video2document/video2document!92
2026-01-15 16:43:13 +01:00
MikeHughes-BIN 9696434145 Enhance module retrieval by categorizing AI and transcription modules 2026-01-15 16:38:59 +01:00
MikeHughes-BIN d84d4f6dee Added last modified 2026-01-15 16:31:00 +01:00
Hughes, Mike 862d4b7a96 Merge branch 'feature/ui-test' into 'develop'
Feature/ui test

See merge request proj-wise2526-video2document/video2document!91
2026-01-15 16:28:51 +01:00
Hughes, Mike 97075e79a6 Merge branch 'feature/customdocument26' into 'feature/ui-test'
Feature/customdocument26

See merge request proj-wise2526-video2document/video2document!90
2026-01-15 14:46:27 +01:00
Hughes, Mike 9fc44bea63 Merge branch 'feature/speaker_renaming' into 'develop'
Remade replace Speaker module which now takes the premade speaker mapping json...

See merge request proj-wise2526-video2document/video2document!89
2026-01-15 14:36:24 +01:00
Hughes, Mike b6f887466b Merge branch 'develop' into 'feature/speaker_renaming'
# Conflicts:
#   main.js
2026-01-15 13:06:07 +01:00
MikeHughes-BIN e40be401c8 Case sensitivity doesnt matter anymore 2026-01-15 10:45:32 +01:00
MikeHughes-BIN 1f96d90a2d Remade replace Speaker module which now takes the premade speaker mapping json and directly replaces speakers in the document. Also refined the Standard documents so consistency is improved 2026-01-15 10:38:28 +01:00
Spanier, Pit 33ce22ec45 Merge branch 'feature/authentication-implementation' into 'develop'
implemented initial version of the authentication system

See merge request proj-wise2526-video2document/video2document!88
2026-01-15 09:59:29 +01:00
Spanier, Pit b9f3967b61 Merge branch 'feature/documentation' into 'develop'
Feature/documentation

See merge request proj-wise2526-video2document/video2document!87
2026-01-15 09:58:38 +01:00
Hughes, Mike 8cd654bcbc Merge branch 'feature/45-extend-readme-s5-01' into 'develop'
Feature/45 extend readme s5 01

See merge request proj-wise2526-video2document/video2document!86
2026-01-15 09:57:56 +01:00
emily 6b3724b765 edited the way api keys are handled.
Since API keys are now loaded from the auth server, this means that there is a delay between starting the software, loading the keys, and loading all the module files.
Due to nodejs running Async, the modules are being loaded BEFORE the api keys have been returned from the auth server.
So now the api keys are being set inside the module every time the module is being called.
This has absolutely no impact on performance, or security, plus, this was the easiest solution, especially as it required no big changes to the rest of the code
2026-01-14 03:01:30 +01:00
emily 5a85a7da4c implemented initial version of the authentication system
Also removed some code that as it turns out, is useless, as electron is a shit software which completely takes over stdin, so there is no way to actually write anything on the CLI
2026-01-14 02:57:51 +01:00
emily 80eb9dac23 removed console.log from the .env file loader 2026-01-14 02:56:14 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 641b17820f Update file README.md 2026-01-12 21:40:11 +01:00
MikeHughes-BIN 11f7db1b1c speaker-renaming module created 2026-01-12 19:07:42 +01:00
Minning, Eric 947e981ac0 Merge branch 'feature/ui-test' into 'develop'
Implemented the script part from the custom_document.html file into the base...

See merge request proj-wise2526-video2document/video2document!85
2026-01-12 18:42:43 +01:00
Aarthi Manivannan, Premanathan Aarthi Manivannan 0010e400b5 Update file README.md 2026-01-11 19:35:15 +01:00
Heyne, Stefan Norbert Robert 4bd6804567 Merge branch 'feature/customdocument26' into 'main'
delete button and function implemented

See merge request proj-wise2526-video2document/video2document!83
2026-01-10 14:29:42 +01:00
emily 6c41da781e initial version of the software documentation 2026-01-08 20:37:06 +01:00
emily 9b8561e4ce euh, removed another unneeded variable .-. 2026-01-08 19:33:10 +01:00
emily 39af2c3312 removed unneeded variable in main.js 2026-01-08 19:32:23 +01:00
emily 9ad335d872 just a line removed so i have something to push to see if the branch creation succeeded 2026-01-08 19:19:09 +01:00
Azeufack Noupeu, Willy 7647398974 Merge branch 'feature/s4-07-parakeet' into 'develop'
S4-07 – Local Parakeet transcription module (Python + NeMo)

See merge request proj-wise2526-video2document/video2document!54
2026-01-08 15:50:47 +01:00
Heyne, Stefan Norbert Robert 4c1897741f Merge branch 'feature/customdocument26' into 'develop'
custom document backend implemented

See merge request proj-wise2526-video2document/video2document!81
2026-01-08 15:39:49 +01:00
Azeufack Noupeu Willy 7e4cf93cae Merge branch 'feature/s4-07-parakeet' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into feature/s4-07-parakeet 2026-01-08 15:26:59 +01:00
Azeufack Noupeu Willy fe86fa1a2f Implemented local Parakeet transcription module (S4-07) 2026-01-08 15:09:59 +01:00
Hughes, Mike cf56947c3b Merge branch 'feature/customdocument26' into 'main'
custom document backend implemented

See merge request proj-wise2526-video2document/video2document!80
2026-01-08 14:32:35 +01:00
Azeufack Noupeu Willy 1e4bde93b1 Merge branch 'develop' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into develop 2026-01-08 13:46:41 +01:00
Hughes, Mike c62ee5aa41 Merge branch 'fix/remove-misleading-env-file' into 'develop'
env example is in UTF 16 which, when copied and used as the .env, is...

See merge request proj-wise2526-video2document/video2document!79
2026-01-07 21:15:29 +01:00
MikeHughes-BIN 9c156a7df3 env example is in UTF 16 which, when copied and used as the .env, is unreadable and breaks the Programm 2025-12-23 13:48:27 +01:00
Hughes, Mike 797898fb8b Merge branch 'develop' into 'main'
Develop

See merge request proj-wise2526-video2document/video2document!78
2025-12-22 14:27:25 +01:00
Minning, Eric 7b630646cc Merge branch 'develop' into 'main'
Develop

See merge request proj-wise2526-video2document/video2document!76
2025-12-22 14:25:10 +01:00
Azeufack Noupeu Willy ee31d26116 Implemented local Parakeet transcription module (S4-07) 2025-12-11 14:52:48 +01:00
Azeufack Noupeu Willy a13fea6734 Merge branch 'develop' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into develop 2025-12-06 14:51:45 +01:00
Azeufack Noupeu Willy e82cf779da Merge branch 'main' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into develop 2025-12-06 14:48:31 +01:00
33 changed files with 2661 additions and 1340 deletions
Vendored
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+322
View File
@@ -54,3 +54,325 @@ Make sure that **ffmpeg** is installed on your system, as it may be required for
--- ---
**Installation complete!** You're now ready to use Video2Document. **Installation complete!** You're now ready to use Video2Document.
###General Despription
## Project Overview
V2D (Video to Document Framework) is a student project developed to convert video and audio content into structured, readable documents using AI-based text processing. The tool is designed to help users automatically generate documents such as meeting reports, summaries or structured texts from recorded videos or audio files.
The main problem V2D addresses is the time-consuming manual effort required to listen to recordings and write documents afterwards. By automating transcription, structuring and document generation, the tool improves efficiency and usability for students, teams and small organizations.
The project was created as part of a university software engineering course and is developed using agile methods (Scrum). It focuses on modular design, usability and extensibility, allowing new document types and features to be added easily.
### Used Packages and Dependencies
This project uses several Node.js packages to handle video processing, AI-based document generation, backend communication, and the desktop user interface. Below is an overview of the most important dependencies and their purpose.
##Core Dependencies:
Electron:
Used to build the desktop application. It allows the project to run as a cross-platform GUI application using web technologies.
Express:
Acts as a lightweight backend server that handles internal API requests and communication between different parts of the application.
Axios:
Used for making HTTP requests, for example when communicating with external APIs such as AI services.
dotenv:
Used to securely load API keys and other sensitive configuration values from environment variables instead of hardcoding them in the source code.
@google/genai:
Provides access to Googles Generative AI models. This package is used to generate structured documents from transcribed text based on configurable prompts.
ffmpeg-static:
Provides a static FFmpeg binary so that video and audio processing works without requiring FFmpeg to be installed separately on the system.
fluent-ffmpeg:
Used together with FFmpeg to process video and audio files, for example extracting audio tracks from uploaded videos.
puppeteer:
Used to render and process HTML content programmatically. This is helpful for document previews and automated content generation.
html-to-docx:
Converts generated HTML documents into downloadable DOCX files, which are provided to the user as the final output.
mocha:
A testing framework used to run unit tests and ensure that core functionalities work as expected.
##Development Dependencies:
TypeScript:
Used to add static typing to the project, improving code quality, readability, and maintainability.
ts-node:
Allows running TypeScript files directly without manually compiling them first.
@types/node:
Provides TypeScript type definitions for Node.js APIs.
@types/fluent-ffmpeg:
Type definitions for fluent-ffmpeg to improve development experience and error checking.
@types/cli-progress:
Provides type support for progress bar functionality used during processing tasks.
###Why These Packages Are Needed
Together, these packages enable:
*Processing video and audio files
*Communicating with AI models for document generation
*Secure handling of API keys
*Generating structured documents (DOCX)
*Providing a user-friendly desktop interface
*Ensuring code quality through testing
###API Keys and Configuration
The V2D Video to Document tool uses external AI and media processing services to convert video and audio content into structured documents.
To access these services, several API keys are required. For security reasons, API keys are not stored in the repository and must be provided via environment variables.
##Supported API Keys
The project currently supports the following API keys. Depending on the configuration and selected provider, one or more of these keys may be used.
Google Gemini API
Environment variable: GOOGLE_API_KEY
Usage:
Used for AI-based document generation. The Large Language Model processes transcripts and creates structured documents such as meeting reports.
OpenAI (ChatGPT)
Environment variable: OPENAI_API_KEY
Usage:
Alternative AI provider for text processing and document generation.
AssemblyAI
Environment variable: ASSEMBLYAI_API_KEY
Usage:
Speech-to-text processing for audio and video files.
Saya
Environment variable: SAYA_API_KEY
Usage:
Additional or experimental AI provider that can be integrated into the document generation pipeline.
##How to Set API Keys
API keys must be configured as environment variables before starting the application.
Linux / macOS
export GOOGLE_API_KEY="your_api_key_here"
export OPENAI_API_KEY="your_api_key_here"
export ASSEMBLYAI_API_KEY="your_api_key_here"
export SAYA_API_KEY="your_api_key_here"
Windows (PowerShell)
setx GOOGLE_API_KEY "your_api_key_here"
setx OPENAI_API_KEY "your_api_key_here"
setx ASSEMBLYAI_API_KEY "your_api_key_here"
setx SAYA_API_KEY "your_api_key_here"
Alternatively, for local development, a .env file can be used:
GOOGLE_API_KEY=your_api_key_here
OPENAI_API_KEY=your_api_key_here
ASSEMBLYAI_API_KEY=your_api_key_here
SAYA_API_KEY=your_api_key_here
⚠️ Important:
The .env file must not be committed to the repository and should be listed in .gitignore.
Security Notes:
*API keys are injected at runtime
*No secrets are stored in the source code
*Prevents accidental exposure of sensitive data
*Supports secure collaboration in GitLab and CI/CD environments
*Follows best practices for secret management
###End-to-End User Guide (Video → Final Document)
This section describes how a user can create a structured document from a video using the V2D Video to Document tool.
Start the Application:
Ensure all required API keys are configured as environment variables.
Install dependencies:
npm install
Start the application:
npm start
The Electron-based GUI will open.
#Upload a Video File:
In the application interface, select Upload Video.
Choose a supported video file (e.g. .mp4, .mov).
The video is loaded into the system for processing.
#Audio Extraction:
The application automatically extracts audio from the uploaded video.
This is handled internally using FFmpeg.
No user interaction is required for this step.
#Speech-to-Text Transcription:
The extracted audio is sent to the speech-to-text service.
The transcription process converts spoken content into text.
The generated transcript is stored internally and used for further processing.
#Select Document Type:
The user selects a document type (e.g. Meeting Report).
Each document type is based on a predefined prompt template.
The selected template defines the structure and style of the final document.
#Document Generation:
The transcript and selected prompt are sent to the AI service.
The AI model processes the input and generates a structured document.
The output is formatted in Markdown.
#Document Preview:
The generated document is displayed in the application preview.
Users can review the content before exporting.
No manual editing is required, but validation is possible.
#Export the Final Document:
The user exports the document in the desired format.
#Supported formats include:
Markdown (.md)
Word (.docx)
The document is saved locally.
#Completion:
The final document is now ready for use.
The user can repeat the process with another video if needed.
###Resources
This section lists the main technologies, libraries, and external resources used in the V2D (Video to Document) project. These resources are required to understand, run, and further develop the application.
##Project Dependencies
The following packages and tools are used in this project (as defined in package.json):
Application & Backend
Node.js JavaScript runtime environment used for backend processing
Electron Framework for building the desktop application
Express Backend web framework for handling requests and internal APIs
AI & API Communication
@google/genai Used for AI-based document generation
Axios HTTP client for communicating with external APIs (LLMs)
Video & Audio Processing
ffmpeg-static Extracts audio from uploaded video files
fluent-ffmpeg Controls FFmpeg operations programmatically
Document Generation & Preview
html-to-docx Converts structured content into Word documents
Puppeteer Renders HTML content for document preview and processing
Configuration & Security
dotenv Loads API keys securely from environment variables
Testing & Development
Mocha Unit testing framework
TypeScript Improves code quality and type safety
These dependencies enable the complete end-to-end workflow from video input to structured document output.
##Relevant Repositories
V2D Main Repository:
https://gitlab.rlp.net/proj-wise2526-video2document/video2document
This repository contains the full source code, configuration files, and documentation for the V2D project.
Downloads & External Resources
The following tools and documentation may be required to run or understand the project:
Node.js: https://nodejs.org
Electron Documentation: https://www.electronjs.org/docs
FFmpeg: https://ffmpeg.org
Google Generative AI: https://ai.google.dev
Puppeteer: https://pptr.dev
+220
View File
@@ -0,0 +1,220 @@
# Documenation of our Program
## Table of Contents
1. [How to run the Software](#how-to-run-the-software)
2. [How it works](#how-it-works)
3. [Modules](#modules)
4. [IPC](#ipc)
5. [Authentication](#authentication)
6. [UI](#ui)
## How to run the Software
If you read the readme file, you will see the basic setup command in order to run the program.
You will need nodejs, the newer the better.
The software is tested with `nodejs-19`, `nodejs-20`, `nodejs-22` and `nodejs-24`.
These versions are confirmed to work with our software, but prior versions may work aswell.
To get nodejs, simply go to their [website](https://nodejs.org/en/download) and download whatever version you want and install it.
Afterward go into the directory of our program, and run the command `npm i`, this will install all the necessary libraries.
Next up you need to set up the .env file.
The file must contain your keys for the modules you want to use.
The .env file looks like this:
```
auth_username=wefhjhjakeghjkahejkghjkaegh
auth_password=wefhjhjakeghjkahejkghjkaegh
```
Once that is done, you can run the command `npm start` to actually start the program.
Alternatively you can double click the start.bat if you are on Windows for example.
## How it works
Our software is fully modular, this means, every part can easily be edited, replaced, removed or added without needing to make many adjustments in the code.
The modules can be found under `./services/modules`
The Structure is as follows:
Inside of `modules` are folders named after the general thing the module does.
For example, `transcription-remote`, this folder contains all the modules that do transcription on a remote service, such as assembly-ai for example.
Inside of these folders we put our modules.
The name of the folder and the module dont matter, as long as the structure is kept, and the module filename ends with .js, it will work.
The program iterates through all of the folders within `./services/modules`, and then iterates over each `.js` file within each of these folders, and then loads them into a specific map called `mapFunctions`.
This map is available ANYWHERE in the backend code, even within a module, which means, you can call a module, from within a module, from within a module, from within yet another module.
## Modules
Building a new module is super easy, any idiot can get it done.
All you need to do is follow the previously mentioned structure.
When you have created your module file, the `.js` file, you simply copy paste this code snippet into it.
```js
module.exports = {
name:"example", // Unique name for our function that will later be used to get the function from the map via "mapFunctions.get("example").function()"
type:"example-type", // value used to differentiate each module to order them in the UI
displayname:"Example", // The displayname used within the UI
async function(randomParameter){
// Here we put a simple console.log to show how the system works
// This function will be called from the @startup.js function in the utility folder
console.log(`\n------------\nThis is the example function called by the ${randomParameter} function\n------------\n`);
}
}
```
If by this point, you cared enough to actually look at the code and the modules and so on, you might have spotted a file in `./services/modules/utility` called `example.js`.
This is a template file that you can just copy paste and use as a base for your new module.
It has the same exact code as mentioned right above.
Now as for how the code works.
Each module is essentially just a JSON object that is being exported, so that the main process can load it into the `mapFunctions` map.
the required fields are as follows
- name: This field contains the internal name through which it will be called. It HAS TO BE unique.
- type: This field contains the type of the module. Is it an LLM module, transcription module, or whatever.
- displayname: This field contains the Displayname used in the UI.
And lastly the function call.
This function call is what is being called by other functions, it is generally the main entrypoint for a module.
Sure, you can always set custom function names, but this is a general solution that works without having to manage function names.
You can always define custom functions inside your module that you call from the entrypoint function, but it is highly advised just to call the entrypoint function from outside of the module as it prevents headaches by just working as intended.
Note, there are also other module fields for specific module types, such as:
- description: Used by any module that needs to be shown on the UI, such as Transcription and LLM modules.
- audioformat: Used by transcription modules to tell the audio extraction module what audio format to use.
## IPC
Our software is split up into 2 pieces, the main process (Backend) and the frontend.
The frontend is written in Electron, so it is essentially just a website.
This makes it relatively easy to edit the frontend.
But it comes with one downside, which is, the frontend and backend cant just directly communicate, you first need to set up an IPC channel between them.
As for the base functionality, all of this is already done.
The frontend gets a list of all the available LLM and Transcription modules sent by the backend on startup.
The JSON object for this information looks like this:
```json
{
"ai_modules":[
{"name": "Example", "displayname": "Example"}
],
"transcription_modules":[
{"name": "Example", "displayname": "Example"}
]
}
```
The backend needs a specific set of informations from the frontend in order to start the pipeline.
The JSON for that looks like this:
```json
{
"video": {
"module": "extraction-video-to-audio",
"inputVideoPath": "A:\\programing\\@projects\\video2document\\test\\unit\\testvideo.mp4"
},
"transcription": {
"module": "assembly"
},
"document": {
"module": "llm-saia_openai_gpt",
"type": "followup-report",
"outputType": "pdf"
}
}
```
As you can see in this JSON object, each part specifies which module is being used for each step.
The module names are each the name field specified in the module itself.
As for the rest of the fields, they are pretty self explanatory except `document.type`, that is a predefined report type.
This is the minimum required setup for the currently implemented pipeline to work.
You can always add fields to it, but dont remove the ones from above.
## Authentication
Our Software uses a custom API key management System.
This system itself is proprietary, and will as such not be delivered with the software.
The way it works is simply via a HTTP request.
In the current version, the main reads the username and password for authentication from the .env file, and then uses these in the header for the HTTP request.
```
hostname: "keyserver.dommymommy.xyz", // The URL to the key server
port: 443, // The Port of the
path: "/v1/auth", // The API Endpoint
method: "GET",
headers: {
"Content-Type": "application/json", // The content type should be JSON
"username": un, // the Username used to authenticate
"password": pw // The password used to authenticate
}
```
### The Important bit of this whole setup
Once the HTTP request is made, it will return a JSON object with the API keys as fields.
One such output could look like this:
```json
{
"ASSEMBLYAI_API_KEY": "eajgjkhgahghahegoikh",
"GOOGLE_API_KEY": "eajgjkhgahghahegoikh",
"SAIA_API_KEY": "eajgjkhgahghahegoikh"
}
```
The key for each entry is being used to store the key in memory.
Specifically under `process.env`
So, if everything in this request worked out, we will have:
```js
process.env.ASSEMBLYAI_API_KEY
process.env.GOOGLE_API_KEY
process.env.SAIA_API_KEY
```
These variables are accessible anywhere in the code and contain the API Keys, so make sure you dont add some untrusted modules that could steal these API Keys.
## UI
The UI has a simple, self-explanatory design, in white and blue.
For easy handling and understanding, the UI is using 6 steps to guide the user through the process and offers a help page
with more defined explanations regarding the steps of the GUI. All parts used in the GUI are stored in the directory `./electron/main`.
Files used for the UI:
- index.html
- style.css
- script.js
- renderer.js
- preload.js
- languages.js
- package-lock.json
- package.json
Folders used for the UI:
- /flags
- /icons
- /node_modules
**index.html:**
This file is the basic framework of our software. Comments in the code define the different UI sections.
The comments are the headlines of the code below them.
**style.css:**
Contains all the css code of the software used in the UI.
**script.js:**
Stores all functions used in the UI.
The code is separated by comments in their matching UI section.
**renderer.js:**
Mainly contains every listener function used in the UI, which listens to any events occuring in the UI,
to handle these events as intended.
The code is separated by comments in their matching UI section.
**preload.js:**
Contains IPC functions to allow communication between the UI and the main process.
**languages.js:**
Holds one JSON, which is used to store the different language variables. These are used
in the script.js for the change of the displayed language of the UI. Add languages here, if
you want to add more options in the language selection.
How to add more languages:
1. Add another language block, like an existing one in the file. (Note: Use every key, which is also used in the other sections,
beside the first key like "eng". This first key should be always unique from the others)
2. Assign the desired values to the keys in the new language section.
How to add more text which changes languages:
1. Create the element in the html file with an unique id.
2. Add this id to every language section and assign them a matching value.
3. Add inside the `script.js` file, inside the `changeLanguage()` function a document call like the others. Except with our id.
**package-log.json:**
It's an electron module file. No changes needed.
**package.json:**
This is an electron base file. No changes needed.
**/flags:**
This directory contains the flags used for the language selection dropdown menu.
**/icons:**
Pictures for the document preview are stored here.
**/node_modules:**
Contains nodes used by electron.
-154
View File
@@ -1,154 +0,0 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Document</title>
<style>
</style>
</head>
<body>
<div class="container">
<h1>Manage document types</h1>
<label for="existingDocs">Vorhandene Dokumententypen auswählen (optional):</label>
<!--Drop Down-->
<select name="existingDocs" id="existingDocs">
<option value="newDoc">-- Neuen Dokumententyp erstellen --</option>
</select>
<div id="docNameWrapper">
<label for="docName">Name des Dokumententyps:</label>
<input type="text" id="docName" placeholder="Gib hier den Namen für den Dokumententyp ein">
</div>
<label for="prompt">Dein Prompt:</label>
<textarea id="prompt" placeholder="Schreibe hier den Prompt für dein Dokumententyp..."></textarea>
<div class="buttons">
<a href="index.html">
<button id="goBackBtn">Abbrechen</button>
</a>
<button id="deleteBtn">Dokumententyp löschen</button>
<button id="generateBtn">Dokumententyp speichern</button>
</div>
<div id="result"></div>
</div>
<script src="languages.js"></script>
<script>
const goBackBtn = document.getElementById("goBackBtn");
const generateBtn = document.getElementById("generateBtn");
const deleteBtn = document.getElementById("deleteBtn");
const existingDocs = document.getElementById("existingDocs");
const docNameInput = document.getElementById("docName");
const promptInput = document.getElementById("prompt");
const resultDiv = document.getElementById("result");
const exampleText = "";
// dokumente speichern
generateBtn.addEventListener("click", () => {
const name = docNameInput.value.trim();
const content = promptInput.value.trim();
if (!name || !content) {
resultDiv.textContent = "Bitte Name des Dokumententyps und Prompt ausfüllen.";
setTimeout(() => {
resultDiv.textContent = "";
}, 3000);
return;
}
window.api.saveTxtFile(name, content).then();
resultDiv.textContent = "Dokumententyp erfolgreich gespeichert!";
setTimeout(() => {
resultDiv.textContent = "";
}, 3000);
reloadDocuments();
});
// dokumente löschen
deleteBtn.addEventListener("click", () => {
const name = docNameInput.value.trim();
if (!name) {
resultDiv.textContent = "Bitte Name des Dokumententyps angeben.";
setTimeout(() => {
resultDiv.textContent = "";
}, 3000);
return;
}
const confirmDelete = confirm(
`Möchtest du den Dokumententyp "${name}" wirklich löschen?`
);
if (!confirmDelete) return;
window.api.deleteTxtFile(name).then((success) => {
if (success) {
resultDiv.textContent = "Dokumententyp erfolgreich gelöscht!";
reloadDocuments();
existingDocs.value = "newDoc";
existingDocs.dispatchEvent(new Event("change"));
} else {
resultDiv.textContent = "Dokumententyp konnte nicht gelöscht werden.";
}
setTimeout(() => {
resultDiv.textContent = "";
}, 3000);
});
});
//function to load existingDoc options to the drop down list
const select = document.getElementById('existingDocs');
window.api.getTxtFiles().then(files => {
reloadDocuments();
});
//content anzeigen
const docNameWrapper = document.getElementById("docNameWrapper");
existingDocs.addEventListener("change", async () => {
const selected = existingDocs.value;
if (selected === "newDoc") {
docNameWrapper.classList.remove("hidden");
docNameInput.value = "";
promptInput.value = exampleText;
return;
}
docNameWrapper.classList.add("hidden");
const content = await window.api.readTxtFile(selected);
promptInput.value = content;
docNameInput.value = selected.replace(".txt", "");
});
//reload drop down
function reloadDocuments() {
[...existingDocs.querySelectorAll('option:not([value="newDoc"])')]
.forEach(o => o.remove());
window.api.getTxtFiles().then(files => {
files.forEach(file => {
const option = document.createElement('option');
option.value = file;
option.textContent = file
.replace('.txt', '') // Endung entfernen
.replace(/_/g, ' ') // Leerzeichen ersetzen
.replace(/\b\w/g, c => c.toUpperCase()) // ersten Buchstaben groß
existingDocs.appendChild(option);
});
});
}
</script>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

-284
View File
@@ -17,302 +17,18 @@
align-items: center; align-items: center;
} }
/* ===== CONTAINER ===== */
.container {
background: white;
width: 90%;
max-width: 800px;
height: 85vh;
/* feste Höhe */
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
}
/* ===== FIXER TOP-BEREICH ===== */
.top-bar {
padding: 15px 20px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
}
/* Buttons */
.back-btn,
.toc-toggle {
background: #007BFF;
color: white;
border: none;
padding: 8px 14px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
}
.back-btn:hover,
.toc-toggle:hover {
background: #0056b3;
}
/* ===== TOC ===== */
.toc-wrapper {
position: relative;
}
.toc {
position: absolute;
right: 0;
top: 45px;
background: white;
border-radius: 8px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
padding: 10px;
min-width: 220px;
display: none;
z-index: 5;
}
.toc a {
display: block;
padding: 8px 10px;
color: #007BFF;
text-decoration: none;
border-radius: 6px;
}
.toc a:hover {
background: #f0f2f5;
}
.toc.show {
display: block;
}
/* ===== SCROLLBEREICH ===== */
.content {
padding: 30px;
overflow-y: auto;
flex: 1;
}
/* Inhalt */
h1 {
text-align: center;
color: #333;
}
.step {
margin-bottom: 20px;
margin-top: 20px;
}
.step h2 {
color: #0056b3;
}
.step h3 {
color: #555;
margin-bottom: 5px;
}
.step p {
color: #555;
line-height: 1.6;
}
.step img {
width: 100%;
max-height: 350px;
object-fit: contain;
border-radius: 8px;
margin-top: 15px;
border: 1px solid #ddd;
}
</style> </style>
</head> </head>
<body> <body>
<div class="container">
<!-- FIXER OBERER TEIL -->
<div class="top-bar">
<a href="index.html">
<button class="back-btn">Zurück</button>
</a>
<h1>Programm Anleitung</h1>
<div class="toc-wrapper">
<button class="toc-toggle" onclick="toggleTOC()">Inhaltsverzeichnis</button>
<div class="toc" id="toc">
<a href="#convertVid" onclick="closeTOC()">Video zu Dokument umwandeln</a>
<a href="#firstStep" onclick="closeTOC()">Schritt 1 - Video auswählen</a>
<a href="#secondStep" onclick="closeTOC()">Schritt 2 - Konfiguration</a>
<a href="#thirdStep" onclick="closeTOC()">Schritt 3 - Dokumententyp auswählen</a>
<a href="#fourthStep" onclick="closeTOC()">Schritt 4 - Bestätigen</a>
<a href="#fifthStep" onclick="closeTOC()">Schritt 5 - Sprecher identifizieren</a>
<a href="#sixthStep" onclick="closeTOC()">Schritt 6 - Dokument speichern</a>
<a href="#createDoc" onclick="closeTOC()">Dokumententyp erstellen</a>
<a href="#editDoc" onclick="closeTOC()">Dokumententyp bearbeiten</a>
<a href="#deleteDoc" onclick="closeTOC()">Dokumententyp löschen</a>
</div>
</div>
</div>
<!-- NUR DIESER TEIL SCROLLT -->
<div class="content">
<div class="step" id="convertVid">
<h2>Video in ein Dokument umwandeln.</h2>
<div class="step" id="firstStep">
<h3>Schritt 1 - Video auswählen</h3>
<p id="firstStep">
- Ziehe eine Videodatei in das Drag-and-Drop-Feld oder klicke auf <strong>„Video
suchen“</strong>,<br>
um eine Datei über deinen Dateibrowser auszuwählen.<br>
- Klicke anschließend auf <strong>Schritt 2</strong> oder auf den blauen Pfeil rechts, um
fortzufahren.
</p>
</div>
<div class="step" id="secondStep">
<h3>Schritt 2 - Konfiguration</h3>
<p>
- Wähle im ersten Auswahlmenü die zu verwendende <strong>KI</strong>.<br>
- Wähle im zweiten Auswahlmenü das zu verwendende <strong>Transkriptions-Tool</strong>.<br>
- Wähle im dritten Auswahlmenü das <strong>Dateiformat</strong> des zu erstellenden
Dokuments.<br>
- Wähle im vierten Auswahlmenü die <strong>Sprache</strong> des zu erstellenden Dokuments.<br>
- Klicke anschließend auf <strong>Schritt 3</strong> oder auf den blauen Pfeil rechts, um
fortzufahren.
</p>
</div>
<div class="step" id="thirdStep">
<h3>Schritt 3 - Dokumententyp auswählen</h3>
<p>
- Wähle einen Dokumententyp über die Checkbox oder einen zuvor erstellten Dokumententyp aus dem
Dropdown-Menü aus.<br>
- Klicke anschließend auf <strong>Schritt 4</strong> oder auf den blauen Pfeil rechts, um
fortzufahren.
</p>
</div>
<div class="step" id="fourthStep">
<h3>Schritt 4 - Bestätigen</h3>
<p>
Klicke auf <strong>„Submit“</strong>, um die Dokumentengenerierung zu starten.<br>
Während der Verarbeitung werden vier Statuspunkte angezeigt, die sich schrittweise von rot zu
grün färben und den aktuellen Fortschritt darstellen:
<br><br>
Punkt 1: Upload und Vorbereitung der Videodatei.<br>
Punkt 2: Transkription des Videoinhalts.<br>
Punkt 3: KI-gestützte Verarbeitung und Dokumentenerstellung.<br>
Punkt 4: Abschluss der Generierung und Bereitstellung des Dokuments.
<br><br>
Nach erfolgreichem Abschluss klicke auf <strong>Schritt 5</strong> oder auf den blauen Pfeil
rechts, um fortzufahren.
</p>
</div>
<div class="step" id="fifthStep">
<h3>Schritt 5 - Sprecher identifizieren</h3>
<p>
Im Auswahlmenü kannst du einen erkannten Sprecher auswählen.<br>
Über den Play-Button lässt sich ein gesprochener Satz anhören, um den Sprecher eindeutig zu
identifizieren.<br>
Mit dem Lautsprecher-Symbol kannst du die Lautstärke anpassen.<br>
Über das Drei-Punkte-Menü lässt sich die Wiedergabegeschwindigkeit einstellen.<br><br>
Im Textfeld <strong>„Write name“</strong> gibst du den tatsächlichen Namen des Sprechers ein,
damit dieser im Dokument
anstelle von Platzhaltern wie z. B. „Sprecher A“ angezeigt wird.<br>
Bestätige die Eingabe mit <strong>„Rename Speaker“</strong>.<br><br>
Mit dem Button <strong>„Rewrite Document“</strong> werden anschließend alle
Sprecherbezeichnungen im Dokument ersetzt.<br><br>
Klicke danach auf <strong>Schritt 6</strong> oder auf den blauen Pfeil rechts, um fortzufahren.
</p>
</div>
<div class="step" id="sixthStep">
<h3>Schritt 6 - Dokument speichern</h3>
<p>
Klicke auf <strong>„Download“</strong>, um das Dokument zu speichern.<br>
Es öffnet sich anschließend ein Dateiexplorer, in dem du den gewünschten Speicherort auswählen
kannst.
</p>
</div>
</div>
<div class="step" id="createDoc">
<h2>Dokumententyp erstellen</h2>
<p>
- Öffne oben links das Burgermenü und wähle den Punkt <strong>„Dokumententypen
verwalten“</strong>.<br>
- Wähle anschließend im Auswahlmenü die Option <strong>„-- Neuen Dokumententyp erstellen
--“</strong>.<br>
- Vergib einen aussagekräftigen Namen für den neuen Dokumententyp.<br>
- Formuliere den Prompt für die KI-gestützte Verarbeitung sorgfältig.<br>
- Klicke auf <strong>Dokumententyp speichern</strong>.<br><br>
<strong>Hinweis:</strong> <br>Der eingegebene Prompt wird unverändert an einen KI-Dienst
übermittelt.
Achte daher unbedingt auf die Einhaltung der geltenden Datenschutzrichtlinien und gib keine
sensiblen oder personenbezogenen Daten ein.
</p>
</div>
<div class="step" id="editDoc">
<h2>Dokumententyp bearbeiten</h2>
<p>
- Öffne oben links das Burgermenü und wähle den Punkt <strong>„Dokumententypen
verwalten“</strong>.<br>
- Wähle anschließend im Auswahlmenü den zu bearbeitenden Dokumententyp aus.<br>
- Überarbeite den bestehenden KI-Prompt oder formuliere einen neuen Prompt.<br>
- Klicke abschließend auf <strong>„Dokumententyp speichern“</strong>.<br><br>
<strong>Hinweis:</strong><br>
Der eingegebene Prompt wird unverändert an einen KI-Dienst übermittelt.
Achte daher unbedingt auf die Einhaltung der geltenden Datenschutzrichtlinien und gib keine
sensiblen oder personenbezogenen Daten ein.
</p>
</div>
<div class="step" id="deleteDoc">
<h2>Dokumententyp löschen</h2>
<p> - Öffne oben links das Burgermenü und wähle den Punkt <strong>„Dokumententypen
verwalten“</strong>.<br>
- Wähle anschließend im Auswahlmenü den zu löschenden Dokumententyp aus.<br>
- Klicke abschließend auf <strong>„Dokumententyp löschen“</strong>.<br><br>
<strong>Hinweis:</strong><br>
Nach Bestätigung des Löschvorgangs kann der Dokumententyp nicht wiederhergestellt werden.
</p>
</div>
</div>
</div>
<script> <script>
function toggleTOC() {
document.getElementById("toc").classList.toggle("show");
}
function closeTOC() {
document.getElementById("toc").classList.remove("show");
}
document.addEventListener("click", function (e) {
const toc = document.getElementById("toc");
const toggle = document.querySelector(".toc-toggle");
if (!toc.contains(e.target) && !toggle.contains(e.target)) {
toc.classList.remove("show");
}
});
</script> </script>
</body> </body>
Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

+266 -92
View File
@@ -1,15 +1,16 @@
<!DOCTYPE html> <!doctype html>
<html lang="de"> <html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title id="title">Video to document</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lc-select@1.3.0/themes/light.css">
</head>
<body>
<div id="h1-wrapper"> <head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title id="title">Video to document</title>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lc-select@1.3.0/themes/light.css" />
</head>
<body>
<div id="h1-wrapper">
<section class="p-menu1"> <section class="p-menu1">
<nav id="navbar" class="navigation" role="navigation"> <nav id="navbar" class="navigation" role="navigation">
<input id="toggle1" type="checkbox" /> <input id="toggle1" type="checkbox" />
@@ -20,49 +21,53 @@
</label> </label>
<nav class="menu1"> <nav class="menu1">
<button id="customDocBtn" onclick="showCD()">Manage document types</button> <button id="customDocBtn" onclick="showCD()">
<a href="help_page.html" class="li1">Help</a> Manage document types
</button>
<button id="helpBtn" onclick="showHelp()">
Help
</button>
</nav> </nav>
</nav> </nav>
</section> </section>
<div class="main_h1">
<h1 id="h1">Video to document</h1> <h1 id="h1">Video to document</h1>
</div>
<div class="gui-language"> <div class="gui-language">
<!-- to do: Ausprobieren mit li, a oder button, im Notfall ohne Flaggen Icons, kein hover--> <select name="language_option" id="language_option"></select>
<select name="language_option" id="language_option"></select> </div>
</div> </div>
</div> <div class="step-nav">
<div class="step-nav">
<div class="step-item active" data-step="1" id="step_nav1">1. Step</div> <div class="step-item active" data-step="1" id="step_nav1">1. Step</div>
<div class="step-item" data-step="2" id="step_nav2">2. Step</div> <div class="step-item" data-step="2" id="step_nav2">2. Step</div>
<div class="step-item" data-step="3" id="step_nav3">3. Step</div> <div class="step-item" data-step="3" id="step_nav3">3. Step</div>
<div class="step-item" data-step="4" id="step_nav4">4. Step</div> <div class="step-item" data-step="4" id="step_nav4">4. Step</div>
<div class="step-item" data-step="5" id="step_nav5">5. Step</div> <div class="step-item" data-step="5" id="step_nav5">5. Step</div>
<div class="step-item" data-step="6" id="step_nav6">6. Step</div> <div class="step-item" data-step="6" id="step_nav6">6. Step</div>
</div> </div>
<div id="middleContainerWrapper" class="middle-container-wrapper"> <div id="middleContainerWrapper" class="middle-container-wrapper">
<button id="prevBtn" class="navBtn" disabled>&larr;</button> <button id="prevBtn" class="navBtn" disabled>&larr;</button>
<!-- Visible middle part--> <!-- Visible middle part-->
<div class="mitte" id="mitte"> <div class="mitte" id="mitte">
<!--Costum document section--> <!--Costum document section-->
<div class="container" id="cdContainer" style="display:none;"> <div class="container" id="cdContainer" style="display: none">
<h1 id="cd_h1">Manage document types</h1> <h1 id="cd_h1">Manage document types</h1>
<label for="existingDocs" id="cd_existingDocs">Select existing documents (optional):</label> <label for="existingDocs" id="cd_existingDocs">Select existing documents (optional):</label>
<!--Drop Down--> <!--Drop Down-->
<select name="existingDocs" id="existingDocs"> <select name="existingDocs" id="existingDocs">
<option value="newDoc" id="newDoc">-- Create new document --</option> <option value="newDoc" id="newDoc">
-- Create new document --
</option>
</select> </select>
<div id="docNameWrapper"> <div id="docNameWrapper">
<label for="docName" id="cd_docName">Document name:</label> <label for="docName" id="cd_docName">Document name:</label>
<input type="text" id="docName" placeholder="Enter the document name here"> <input type="text" id="docName" placeholder="Enter the document name here" />
</div> </div>
<label for="prompt" id="cd_promt">Your prompt:</label> <label for="prompt" id="cd_promt">Your prompt:</label>
@@ -77,25 +82,164 @@
<div id="result"></div> <div id="result"></div>
</div> </div>
<!-- Here starts code from the helppage -->
<div class="containerHelp" id="helpContainer" style="display: none">
<!-- FIXER OBERER TEIL -->
<div class="top-bar" id="top_bar_help">
<button class="back-btn" id="back_btn" onclick="showHelp()">Return</button>
<h1 id="help_page_h1">Programm tutorial</h1>
<div class="toc-wrapper">
<button class="toc-toggle" id="help_page_tableofcontents" onclick="toggleTOC()">Table of contents</button>
<div class="toc" id="toc">
<a href="#convertVid" id='hp_convertVid' onclick="closeTOC()">Convert video to document</a>
<a href="#firstStep" id='hp_firstStep' onclick="closeTOC()">Step 1 - Select video</a>
<a href="#secondStep" id='hp_secondStep' onclick="closeTOC()">Step 2 - Configuration</a>
<a href="#thirdStep" id='hp_thirdStep' onclick="closeTOC()">Step 3 - Select document type</a>
<a href="#fourthStep" id='hp_fourthStep' onclick="closeTOC()">Step 4 - Confirm</a>
<a href="#fifthStep" id='hp_fifthStep' onclick="closeTOC()">Step 5 - Identify speakers</a>
<a href="#sixthStep" id='hp_sixthStep' onclick="closeTOC()">Step 6 - Save document</a>
<a href="#createDoc" id='hp_createDoc' onclick="closeTOC()">Create document type</a>
<a href="#editDoc" id='hp_editDoc' onclick="closeTOC()">Edit document type</a>
<a href="#deleteDoc" id='hp_deleteDoc' onclick="closeTOC()">Delete document type</a>
</div>
</div>
</div>
<!-- NUR DIESER TEIL SCROLLT -->
<div class="content" id="content">
<div class="step_hp" id="convertVid">
<h2 id="hp_convertVid_h2">Convert video to document.</h2>
<div class="step_hp" id="firstStep">
<h3 id="hp_firstStep_h3">Step 1 - Select video</h3>
<p id="hp_firstStep_p">
- Drag a video file into the drag-and-drop field or click <strong>“Search video”</strong>,<br>to select
a file using your file browser.<br>- Then click <strong>Step 2</strong> or the blue arrow on the right
to continue.
</p>
</div>
<div class="step_hp" id="secondStep">
<h3 id="hp_secondStep_h3">Step 2 - Configuration</h3>
<p id="hp_secondStep_p">
- Select the <strong>AI</strong> to be used in the first dropdown menu.<br>- Select the
<strong>transcription tool</strong> to be used in the second dropdown menu.<br>- Select the <strong>file
format</strong> of the document to be created in the third dropdown menu.<br>- Select the
<strong>language</strong> of the document to be created in the fourth dropdown menu.<br>- Then click
<strong>Step 3</strong> or the blue arrow on the right to continue.
</p>
</div>
<div class="step_hp" id="thirdStep">
<h3 id="hp_thirdStep_h3">Step 3 - Select document type</h3>
<p id="hp_thirdStep_p">
Select a document type using the checkbox or choose a previously created document type from the dropdown
menu.<br>- Then click <strong>Step 4</strong> or the blue arrow on the right to continue.
</p>
</div>
<div class="step_hp" id="fourthStep">
<h3 id="hp_fourthStep_h3">Step 4 - Confirm</h3>
<p id="hp_fourthStep_p">
Click <strong>“Submit”</strong> to start the document generation.<br>During processing, four status
indicators are displayed that gradually change from red to green and show the current
progress:<br><br>Indicator 1: Upload and preparation of the video file.<br>Indicator 2: Transcription of
the video content.<br>Indicator 3: AI-based processing and document creation.<br>Indicator 4: Completion
of generation and provision of the document.<br><br>After successful completion, click <strong>Step
5</strong> or the blue arrow on the right to continue.
</p>
</div>
<div class="step_hp" id="fifthStep">
<h3 id="hp_fifthStep_h3">Step 5 - Identify speakers</h3>
<p id="hp_fifthStep_p">
In the dropdown menu, you can select a recognized speaker.<br>Using the play button, you can listen to a
spoken sentence to clearly identify the speaker.<br>With the speaker icon, you can adjust the
volume.<br>Using the three-dot menu, you can set the playback speed.<br><br>In the text field
<strong>“Write name”</strong>, enter the actual name of the speaker so that it is displayed in the
document instead of placeholders such as “Speaker A”.<br>Confirm the entry with <strong>“Rename
Speaker”</strong>.<br><br>With the <strong>“Rewrite Document”</strong> button, all speaker labels in
the document are then replaced.<br><br>After that, click <strong>Step 6</strong> or the blue arrow on
the right to continue.
</p>
</div>
<div class="step_hp" id="sixthStep">
<h3 id="hp_sixthStep_h3">Step 6 - Save document</h3>
<p id="hp_sixthStep_p">
Click <strong>“Download”</strong> to save the document.<br>A file explorer will then open, where you can
select the desired storage location.
</p>
</div>
</div>
<div class="step_hp" id="createDoc">
<h2 id="hp_createDoc_h2">Create document type</h2>
<p id="hp_createDoc_p">
- Open the burger menu at the top left and select <strong>“Manage document types”</strong>.<br>- Then
select the option <strong>“-- Create new document type --”</strong> from the dropdown menu.<br>- Enter a
descriptive name for the new document type.<br>- Carefully formulate the prompt for the AI-based
processing.<br>- Click <strong>Save document type</strong>.<br><br><strong>Note:</strong><br>The entered
prompt is transmitted unchanged to an AI service. Therefore, make sure to comply with applicable data
protection regulations and do not enter any sensitive or personal data.
</p>
</div>
<div class="step_hp" id="editDoc">
<h2 id="hp_editDoc_h2">Edit document type</h2>
<p id="hp_editDoc_p">
- Open the burger menu at the top left and select <strong>“Manage document types”</strong>.<br>- Then
select the document type to be edited from the dropdown menu.<br>- Revise the existing AI prompt or
formulate a new prompt.<br>- Finally, click <strong>“Save document
type”</strong>.<br><br><strong>Note:</strong><br>The entered prompt is transmitted unchanged to an AI
service. Therefore, make sure to comply with applicable data protection regulations and do not enter any
sensitive or personal data.
</p>
</div>
<div class="step_hp" id="deleteDoc">
<h2 id="hp_deleteDoc_h2">Delete document type</h2>
<p id="hp_deleteDoc_p">
- Open the burger menu at the top left and select <strong>“Manage document types”</strong>.<br>- Then
select the document type to be deleted from the dropdown menu.<br>- Finally, click <strong>“Delete
document type”</strong>.<br><br><strong>Note:</strong><br>After confirming the deletion process, the
document type cannot be restored.
</p>
</div>
</div>
</div>
<!-- Here starts code from step 1--> <!-- Here starts code from step 1-->
<div class="step" id="step1"> <div class="step" id="step1">
<h2 class="h2">Upload your video here:</h2> <h2 class="h2" id="step1_h2">Upload your video here:</h2>
<div class="upload-container" id="uploadContainer"> <div class="upload-container" id="uploadContainer">
<p id="p1">Drag and drop video file</p> <p id="p1">Drag and drop video file</p>
<video id="previewThumbnail" autoplay="false"> <video id="previewThumbnail" autoplay="false"></video>
</video>
<div class="file-name" id="fileName">No video chosen</div> <div class="file-name" id="fileName">No video chosen</div>
<div id="thumbnailContainer"> <div id="thumbnailContainer">
<img id="thumbnailImage" style="display:none;"> <img id="thumbnailImage" style="display: none" />
</div> </div>
<button class="custom-btn" id="manualUploadBtn">Search video</button> <button class="custom-btn" id="manualUploadBtn">
<input type="file" id="videoUpload" accept="video/*"> Search video
</button>
<input type="file" id="videoUpload" accept="video/*" />
</div> </div>
</div> </div>
<!-- Here starts code from step 2--> <!-- Here starts code from step 2-->
<div class="step" id="step2" style="display:none;"> <div class="step" id="step2" style="display: none">
<h2 class="h2">Choose your preferences:</h2> <h2 class="h2" id="step2_h2">Choose your preferences:</h2>
<div class="step2-form">
<div class="KI-wrapper"> <div class="KI-wrapper">
<label id="labelKI">Select ki:</label> <label id="labelKI">Select ki:</label>
<select name="ai_type" id="ai_type"></select> <select name="ai_type" id="ai_type"></select>
@@ -110,7 +254,7 @@
<label id="labelType">Select type:</label> <label id="labelType">Select type:</label>
<select name="output_type" id="output_type"> <select name="output_type" id="output_type">
<option value="pdf">.pdf</option> <option value="pdf">.pdf</option>
<option value="word">.docx</option> <option value="docx">.docx</option>
<option value="txt">.txt</option> <option value="txt">.txt</option>
</select> </select>
</div> </div>
@@ -118,106 +262,136 @@
<div class="language-wrapper"> <div class="language-wrapper">
<label id="labelLanguage">Select language:</label> <label id="labelLanguage">Select language:</label>
<select name="document_language_option" id="document_language_option"> <select name="document_language_option" id="document_language_option"></select>
</div>
</select>
</div> </div>
</div> </div>
<!-- Here starts code from step 3--> <!-- Here starts code from step 3-->
<!-- Hover Effekt für Dokumentenvorschau, Fragezeichen hinter Text, drüber hoven zeigt Beispieldokument --> <!-- Hover Effekt für Dokumentenvorschau, Fragezeichen hinter Text, drüber hoven zeigt Beispieldokument -->
<div class="step" id="step3" style="display:none;"> <div class="step" id="step3" style="display: none">
<div class="checkbox-group"> <div class="checkbox-group">
<h2 class="h2">Choose prefered document style:</h2> <h2 class="h2" id="step3_h2">Choose prefered document style:</h2>
<div class="checkbox-container"> <div class="checkbox-container">
<input type="checkbox" name ="docFormat" id="docFormat" value="followup-report"> <input type="checkbox" name="docFormat" id="docFormat" value="followup-report" />
<label id="label_format" for="docFormat">Follow-up Report</label> <label id="label_format" for="docFormat">Follow-up Report</label>
<div class="figure1"> <div class="figure1">
<img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png"> <img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png" />
<img class="img-hover1" src="flags/germany-flag-png-large.jpg"> <img class="img-hover1" src="icons/follow_up_report_example.png" />
</div> </div>
</div> </div>
<div class="checkbox-container"> <div class="checkbox-container">
<input type="checkbox" name="docFormat" id="docFormatSummary1" value="agenda"> <input type="checkbox" name="docFormat" id="docFormatSummary1" value="agenda" />
<label id="label_summary" for="docFormatSummary">Agenda</label> <label id="label_summary" for="docFormatSummary">Agenda</label>
<img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png"> <div class="figure2">
<img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png" />
<img class="img-hover2" src="icons/agenda_example.png" />
</div>
</div> </div>
<div class="checkbox-container"> <div class="checkbox-container">
<input type="checkbox" name="docFormat" id="docFormatSummary2" value="result-protocol"> <input type="checkbox" name="docFormat" id="docFormatSummary2" value="result-protocol" />
<label id="label_summary" for="docFormatSummary">Resultprotocol</label> <label id="label_summary_result" for="docFormatSummary">Resultprotocol</label>
<img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png"> <div class="figure3">
<img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png" />
<img class="img-hover3" src="icons/result_protocol_example.png" />
</div>
</div> </div>
<div class="checkbox-container"> <div class="checkbox-container">
<input type="checkbox" name="docFormat" id="docFormatSummary3" value="sprint-planning"> <input type="checkbox" name="docFormat" id="docFormatSummary3" value="sprint-planning" />
<label id="label_summary" for="docFormatSummary">Sprint Planning Note</label> <label id="label_summary_note" for="docFormatSummary">Sprint Planning Note</label>
<img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png"> <div class="figure4">
<img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png" />
<img class="img-hover4" src="icons/sprint_planning_note_example.png" />
</div>
</div> </div>
<div class="checkbox-container"> <div class="checkbox-container">
<input type="checkbox" name="docFormat" id="docFormatCustom" value="custom"> <input type="checkbox" name="docFormat" id="docFormatCustom" value="custom" />
<select name="customDocumentTypes" id="customDocumentTypes"> <select name="customDocumentTypes" id="customDocumentTypes"></select>
</select>
</div> </div>
</div> </div>
</div> </div>
<!-- Here starts code from step 4--> <!-- Here starts code from step 4-->
<div class="step" id="step4" style="display:none;"> <div class="step" id="step4" style="display: none">
<h2 class="h2">Click to submit:</h2> <h2 class="h2" id="step4_h2">Click to submit:</h2>
<button class="submit-btn" id="submitButton" onclick="checkBoxes()" disabled>Submit</button> <button class="submit-btn" id="submitButton" onclick="checkBoxes()" disabled>
Submit
</button>
<div class="testy" id="testy"> <div class="testy" id="testy">
<div class="box2" id="box1"> <div class="box2" id="box1"></div>
</div>
<p id="box1_p1">---Starting---</p> <p id="box1_p1">---Starting---</p>
<div class="box2" id="box2"> <div class="box2" id="box2"></div>
</div>
<p id="box2_p2">---Transkribing---</p> <p id="box2_p2">---Transkribing---</p>
<div class="box2" id="box3"> <div class="box2" id="box3"></div>
</div>
<p id="box3_p3">---Document creation---</p> <p id="box3_p3">---Document creation---</p>
<div class="box2" id="box4"> <div class="box2" id="box4"></div>
</div>
</div> </div>
</div> </div>
<!-- Here starts code from step 5--> <!-- Here starts code from step 5-->
<div class="step" id="step5" style="display:none;"> <div class="step" id="step5" style="display: none">
<h2 class="h2">Change names of the speakers:</h2> <h2 class="h2" id="step5_h2">Change names of the speakers:</h2>
<div class="speakerView" id="speakerView">
<label id="labelSpeaker">Select Speaker:</label> <div class="speaker-container">
<select name="cur_speaker" id="cur_speaker"> <table class="speaker-table">
</select> <tbody>
</div> <tr>
<div class="speakerAudio" id="speakerAutio"> <td class="label-cell">
<label id="labelSpeakerAudio">Selected Speaker:</label> <label id="labelSpeaker" for="cur_speaker">Select Speaker:</label>
</td>
<td class="input-cell">
<select name="cur_speaker" id="cur_speaker"></select>
</td>
</tr>
<tr>
<td class="label-cell">
<label id="labelSpeakerAudio">Speaker Audio:</label>
</td>
<td class="input-cell">
<audio controls id="speakerAudioViewer"> <audio controls id="speakerAudioViewer">
Currently there is no audio file here. Currently there is no audio file here.
</audio> </audio>
</td>
</tr>
<tr>
<td class="label-cell">
<label id="labelSpeakerWriter" for="newSpeaker">New Name:</label>
</td>
<td class="input-cell">
<input type="text" id="newSpeaker" placeholder="Enter new speaker name" />
</td>
</tr>
</tbody>
</table>
<div class="speaker-button-group">
<button id="speakerLocker" onclick="rewriteSpeakerName()">
Rename Speaker
</button>
<button id="speakerResender" onclick="sendSpeakerPackages()">
Rewrite Document
</button>
</div> </div>
<div class="speakerWrite" id="speakerWrite">
<label id="labelSpeakerWriter">Write name:</label>
<input type="text" id="newSpeaker">
</div>
<div class="speakerButton-group">
<button id="speakerLocker" onclick="rewriteSpeakerName()">Rename Speaker</button>
<button id="speakerResender" onclick="sendSpeakerPackages()">Rewrite document</button>
</div> </div>
</div> </div>
<!-- Here starts code from step 6--> <!-- Here starts code from step 6-->
<div class="step" id="step6" style="display:none;"> <div class="step" id="step6" style="display: none">
<h2 class="h2">Klick to download your document:</h2> <h2 class="h2" id="step6_h2">Click to download your document:</h2>
<button class="download-btn" id="downloadButton" onclick="fileDownload()">Download</button> <button class="download-btn" id="downloadButton" onclick="fileDownload()">
Download
</button>
</div> </div>
</div> </div>
<button id ="nextBtn" class="navBtn">&rarr;</button> <button id="nextBtn" class="navBtn">&rarr;</button>
</div>
</div> <script src="https://cdn.jsdelivr.net/npm/lc-select@1.3.0/lc_select.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lc-select@1.3.0/lc_select.min.js"></script> <script src="languages.js"></script>
<script src="languages.js"></script> <script src="script.js"></script>
<script src="script.js"></script> <script src="./renderer.js"></script>
<script src="./renderer.js"></script>
</body> </body>
</html> </html>
+345 -31
View File
@@ -1,7 +1,7 @@
var languageOptions = { var languageOptions = {
"eng":{ "eng":{
"flagPath": "flags/united-kingdom-flag-png-large.jpg", "flagPath": "flags/united-kingdom-flag-png-large.jpg",
"labelKI": "Select ki:", "labelKI": "Select AI:",
"labelTranscription": "Select transcription:", "labelTranscription": "Select transcription:",
"labelLanguage": "Select language:", "labelLanguage": "Select language:",
"title": "Video to document", "title": "Video to document",
@@ -9,9 +9,11 @@ var languageOptions = {
"p1": "Drag and drop video file", "p1": "Drag and drop video file",
"fileName": "No video chosen", "fileName": "No video chosen",
"manualUploadBtn": "Search video", "manualUploadBtn": "Search video",
"checkbox_group": "Choose prefered document style:", "checkbox_group": "Choose preferred document style:",
"label_format": "Meeting report", "label_format": "Follow-up Report",
"label_summary": "Summary with timestamps", "label_summary": "Agenda",
"label_summary_result": "Resultprotocol",
"label_summary_note" : "Sprint Planning Note",
"submitButton": "Submit", "submitButton": "Submit",
"step_nav1": "Step 1", "step_nav1": "Step 1",
"step_nav2": "Step 2", "step_nav2": "Step 2",
@@ -27,7 +29,7 @@ var languageOptions = {
"speakerResender": "Rewrite document", "speakerResender": "Rewrite document",
"downloadButton": "Download", "downloadButton": "Download",
"box1_p1": "---Starting---", "box1_p1": "---Starting---",
"box2_p2": "---Transkribing---", "box2_p2": "---Transcribing---",
"box3_p3": "---Document creation---", "box3_p3": "---Document creation---",
"labelType": "Select document type:", "labelType": "Select document type:",
@@ -41,22 +43,69 @@ var languageOptions = {
"goBackBtn": "Return", "goBackBtn": "Return",
"deleteBtn": "Delete document", "deleteBtn": "Delete document",
"generateBtn": "Save document", "generateBtn": "Save document",
"newDoc": "-- Create new document --" "newDoc": "-- Create new document --",
"step1_h2" : "Upload your video here:",
"step2_h2" : "Choose your preferences:",
"step3_h2" : "Choose prefered document style:",
"step4_h2" : "Click to submit:",
"step5_h2" : "Change names of the speakers:",
"step6_h2" : "Click to download your document:",
//help page
"back_btn" : "Back",
"help_page_h1" : "Programm tutorial",
"help_page_tableofcontents" : "Table of contents",
//Inhaltsverzeichnis
"hp_convertVid" : "Convert video to document",
"hp_firstStep" : "Step 1 - Select video",
"hp_secondStep" : "Step 2 - Configuration",
"hp_thirdStep" : "Step 3 - Select document type",
"hp_fourthStep" : "Step 4 - Confirm",
"hp_fifthStep" : "Step 5 - Identify speakers",
"hp_sixthStep" : "Step 6 - Save document",
"hp_createDoc" : "Create document type",
"hp_editDoc" : "Edit document type",
"hp_deleteDoc" : "Delete document type",
//Ueberschriften
"hp_convertVid_h2" : "Convert video to document.",
"hp_firstStep_h3" : "Step 1 - Select video",
"hp_secondStep_h3" : "Step 2 - Configuration",
"hp_thirdStep_h3" : "Step 3 - Select document type",
"hp_fourthStep_h3" : "Step 4 - Confirm",
"hp_fifthStep_h3" : "Step 5 - Identify speakers",
"hp_sixthStep_h3" : "Step 6 - Save document",
"hp_createDoc_h2" : "Create document type",
"hp_editDoc_h2" : "Edit document type",
"hp_deleteDoc_h2" : "Delete document type",
//Texte
"hp_firstStep_p" : "- Drag a video file into the drag-and-drop field or click <strong>“Search video”</strong>,<br>to select a file using your file browser.<br>- Then click <strong>Step 2</strong> or the blue arrow on the right to continue.",
"hp_secondStep_p" : "- Select the <strong>AI</strong> to be used in the first dropdown menu.<br>- Select the <strong>transcription tool</strong> to be used in the second dropdown menu.<br>- Select the <strong>file format</strong> of the document to be created in the third dropdown menu.<br>- Select the <strong>language</strong> of the document to be created in the fourth dropdown menu.<br>- Then click <strong>Step 3</strong> or the blue arrow on the right to continue.",
"hp_thirdStep_p" : "- Select a document type using the checkbox or choose a previously created document type from the dropdown menu.<br>- Then click <strong>Step 4</strong> or the blue arrow on the right to continue.",
"hp_fourthStep_p" : "Click <strong>“Submit”</strong> to start the document generation.<br>During processing, four status indicators are displayed that gradually change from red to green and show the current progress:<br><br>Indicator 1: Upload and preparation of the video file.<br>Indicator 2: Transcription of the video content.<br>Indicator 3: AI-based processing and document creation.<br>Indicator 4: Completion of generation and provision of the document.<br><br>After successful completion, click <strong>Step 5</strong> or the blue arrow on the right to continue.",
"hp_fifthStep_p" : "In the dropdown menu, you can select a recognized speaker.<br>Using the play button, you can listen to a spoken sentence to clearly identify the speaker.<br>With the speaker icon, you can adjust the volume.<br>Using the three-dot menu, you can set the playback speed.<br><br>In the text field <strong>“Write name”</strong>, enter the actual name of the speaker so that it is displayed in the document instead of placeholders such as “Speaker A”.<br>Confirm the entry with <strong>“Rename Speaker”</strong>.<br><br>With the <strong>“Rewrite Document”</strong> button, all speaker labels in the document are then replaced.<br><br>After that, click <strong>Step 6</strong> or the blue arrow on the right to continue.",
"hp_sixthStep_p" : "Click <strong>“Download”</strong> to save the document.<br>A file explorer will then open, where you can select the desired storage location.",
"hp_createDoc_p" : "- Open the burger menu at the top left and select <strong>“Manage document types”</strong>.<br>- Then select the option <strong>“-- Create new document type --”</strong> from the dropdown menu.<br>- Enter a descriptive name for the new document type.<br>- Carefully formulate the prompt for the AI-based processing.<br>- Click <strong>Save document type</strong>.<br><br><strong>Note:</strong><br>The entered prompt is transmitted unchanged to an AI service. Therefore, make sure to comply with applicable data protection regulations and do not enter any sensitive or personal data.",
"hp_editDoc_p" : "- Open the burger menu at the top left and select <strong>“Manage document types”</strong>.<br>- Then select the document type to be edited from the dropdown menu.<br>- Revise the existing AI prompt or formulate a new prompt.<br>- Finally, click <strong>“Save document type”</strong>.<br><br><strong>Note:</strong><br>The entered prompt is transmitted unchanged to an AI service. Therefore, make sure to comply with applicable data protection regulations and do not enter any sensitive or personal data.",
"hp_deleteDoc_p" : "- Open the burger menu at the top left and select <strong>“Manage document types”</strong>.<br>- Then select the document type to be deleted from the dropdown menu.<br>- Finally, click <strong>“Delete document type”</strong>.<br><br><strong>Note:</strong><br>After confirming the deletion process, the document type cannot be restored."
}, },
"de":{ "de":{
"flagPath": "flags/germany-flag-png-large.jpg", "flagPath": "flags/germany-flag-png-large.jpg",
"labelKI": "Waehle KI:", "labelKI": "Wähle KI:",
"labelTranscription": "Waehle Transkription:", "labelTranscription": "Wähle Transkription:",
"labelLanguage": "Waehle Sprache:", "labelLanguage": "Wähle Sprache:",
"title": "Video zu Dokument", "title": "Video zu Dokument",
"h1": "Video zu Dokument", "h1": "Video zu Dokument",
"p1": "Video per Drag & Drop ablegen", "p1": "Video per Drag & Drop ablegen",
"fileName": "Kein Video ausgewaehlt", "fileName": "Kein Video ausgewählt",
"manualUploadBtn": "Video suchen", "manualUploadBtn": "Video suchen",
"checkbox_group": "Bevorzugte Dokumentvarianten:", "checkbox_group": "Bevorzugte Dokumentvarianten:",
"label_format": "Meeting Bericht", "label_format": "Folgebericht",
"label_summary": "Zusammenfassung mit Zeitstempeln", "label_summary": "Agenda",
"label_summary_result": "Ergebnisprotokoll",
"label_summary_note" : "Sprint-Planungshinweis",
"submitButton": "Absenden", "submitButton": "Absenden",
"step_nav1": "Schritt 1", "step_nav1": "Schritt 1",
"step_nav2": "Schritt 2", "step_nav2": "Schritt 2",
@@ -64,7 +113,7 @@ var languageOptions = {
"step_nav4": "Schritt 4", "step_nav4": "Schritt 4",
"step_nav5": "Schritt 5", "step_nav5": "Schritt 5",
"step_nav6": "Schritt 6", "step_nav6": "Schritt 6",
"h2": "Uploade dein Video hier:", "h2": "Lade dein Video hier hoch:",
"labelSpeaker": "Wähle Sprecher:", "labelSpeaker": "Wähle Sprecher:",
"labelSpeakerAudio": "Ausgewählter Sprecher:", "labelSpeakerAudio": "Ausgewählter Sprecher:",
"labelSpeakerWriter": "Schreib Namen:", "labelSpeakerWriter": "Schreib Namen:",
@@ -72,36 +121,83 @@ var languageOptions = {
"speakerResender": "Überschreibe Dokument", "speakerResender": "Überschreibe Dokument",
"downloadButton": "Download", "downloadButton": "Download",
"box1_p1": "---Startet---", "box1_p1": "---Startet---",
"box2_p2": "---Transkribing---", "box2_p2": "---Transkribierung---",
"box3_p3": "---Dokument kreieren---", "box3_p3": "---Dokument erstellen---",
"labelType": "Wähle Dokumenttype:", "labelType": "Wähle Dokumenttyp:",
"customDocBtn": "Dokumenttypen verwalten", "customDocBtn": "Dokumenttypen verwalten",
"cd_h1": "Dokumenttypen verwalten", "cd_h1": "Dokumenttypen verwalten",
"cd_existingDocs": "Vorhandene Dokumente auswählen (optional):", "cd_existingDocs": "Vorhandene Dokumente auswählen (optional):",
"cd_docName": "Dokument Name", "cd_docName": "Dokumentname",
"docName": "Geben Sie hier den Dokumentnamen ein", "docName": "Geben Sie hier den Dokumentnamen ein",
"cd_promt": "Ihr Prompt:", "cd_promt": "Ihr Prompt:",
"prompt": "Geben Sie hier die Eingabeaufforderung für Ihr Dokument ein...", "prompt": "Geben Sie hier die Eingabeaufforderung für Ihr Dokument ein...",
"goBackBtn": "Zurück", "goBackBtn": "Zurück",
"deleteBtn": "Lösche Dokument", "deleteBtn": "Lösche Dokument",
"generateBtn": "Speicher Dokument", "generateBtn": "Speichere Dokument",
"newDoc": "-- Neues Dokument erstellen --" "newDoc": "-- Neues Dokument erstellen --",
"step1_h2" : "Laden Sie Ihr Video hier hoch:",
"step2_h2" : "Wählen Sie Ihre Präferenzen:",
"step3_h2" : "Wählen Sie den gewünschten Dokumentstil:",
"step4_h2" : "Zum Absenden klicken:",
"step5_h2" : "Ändern Sie die Namen der Sprecher:",
"step6_h2" : "Klicken Sie hier, um Ihr Dokument herunterzuladen:",
//help page
"back_btn" : "Zurück",
"help_page_h1" : "Programm Anleitung",
"help_page_tableofcontents" : "Inhaltsverzeichnis",
//Inhaltsverzeichnis
"hp_convertVid" : "Video zu Dokument umwandeln",
"hp_firstStep" : "Schritt 1 - Video auswählen",
"hp_secondStep" : "Schritt 2 - Konfiguration",
"hp_thirdStep" : "Schritt 3 - Dokumententyp auswählen",
"hp_fourthStep" : "Schritt 4 - Bestätigen",
"hp_fifthStep" : "Schritt 5 - Sprecher identifizieren",
"hp_sixthStep" : "Schritt 6 - Dokument speichern",
"hp_createDoc" : "Dokumententyp erstellen",
"hp_editDoc" : "Dokumententyp bearbeiten",
"hp_deleteDoc" : "Dokumententyp löschen",
//Ueberschriften
"hp_convertVid_h2" : "Video zu Dokument umwandeln.",
"hp_firstStep_h3" : "Schritt 1 - Video auswählen",
"hp_secondStep_h3" : "Schritt 2 - Konfiguration",
"hp_thirdStep_h3" : "Schritt 3 - Dokumententyp auswählen",
"hp_fourthStep_h3" : "Schritt 4 - Bestätigen",
"hp_fifthStep_h3" : "Schritt 5 - Sprecher identifizieren",
"hp_sixthStep_h3" : "Schritt 6 - Dokument speichern",
"hp_createDoc_h2" : "Dokumententyp erstellen",
"hp_editDoc_h2" : "Dokumententyp bearbeiten",
"hp_deleteDoc_h2" : "Dokumententyp löschen",
//Texte
"hp_firstStep_p" : '- Ziehe eine Videodatei in das Drag-and-Drop-Feld oder klicke auf <strong>„Video suchen“</strong>,<br>um eine Datei über deinen Dateibrowser auszuwählen.<br>- Klicke anschließend auf <strong>Schritt 2</strong> oder auf den blauen Pfeil rechts, um fortzufahren.',
"hp_secondStep_p" : '- Wähle im ersten Auswahlmenü die zu verwendende <strong>KI</strong>.<br>- Wähle im zweiten Auswahlmenü das zu verwendende <strong>Transkriptions-Tool</strong>.<br>- Wähle im dritten Auswahlmenü das <strong>Dateiformat</strong> des zu erstellenden Dokuments.<br>- Wähle im vierten Auswahlmenü die <strong>Sprache</strong> des zu erstellenden Dokuments.<br>- Klicke anschließend auf <strong>Schritt 3</strong> oder auf den blauen Pfeil rechts, um fortzufahren.',
"hp_thirdStep_p" : '- Wähle einen Dokumententyp über die Checkbox oder einen zuvor erstellten Dokumententyp aus dem Dropdown-Menü aus.<br>- Klicke anschließend auf <strong>Schritt 4</strong> oder auf den blauen Pfeil rechts, um fortzufahren.',
"hp_fourthStep_p" : 'Klicke auf <strong>„Submit“</strong>, um die Dokumentengenerierung zu starten.<br>Während der Verarbeitung werden vier Statuspunkte angezeigt, die sich schrittweise von rot zu grün färben und den aktuellen Fortschritt darstellen:<br><br>Punkt 1: Upload und Vorbereitung der Videodatei.<br>Punkt 2: Transkription des Videoinhalts.<br>Punkt 3: KI-gestützte Verarbeitung und Dokumentenerstellung.<br>Punkt 4: Abschluss der Generierung und Bereitstellung des Dokuments.<br><br>Nach erfolgreichem Abschluss klicke auf <strong>Schritt 5</strong> oder auf den blauen Pfeil rechts, um fortzufahren.',
"hp_fifthStep_p" : 'Im Auswahlmenü kannst du einen erkannten Sprecher auswählen.<br>Über den Play-Button lässt sich ein gesprochener Satz anhören, um den Sprecher eindeutig zuidentifizieren.<br>Mit dem Lautsprecher-Symbol kannst du die Lautstärke anpassen.<br>Über das Drei-Punkte-Menü lässt sich die Wiedergabegeschwindigkeit einstellen.<br><br>Im Textfeld <strong>„Write name“</strong> gibst du den tatsächlichen Namen des Sprechers ein, damit dieser im Dokument anstelle von Platzhaltern wie z. B. „Sprecher A“ angezeigt wird.<br>Bestätige die Eingabe mit <strong>„Rename Speaker“</strong>.<br><br>Mit dem Button <strong>„Rewrite Document“</strong> werden anschließend alle Sprecherbezeichnungen im Dokument ersetzt.<br><br>Klicke danach auf <strong>Schritt 6</strong> oder auf den blauen Pfeil rechts, um fortzufahren.',
"hp_sixthStep_p" : 'Klicke auf <strong>„Download“</strong>, um das Dokument zu speichern.<br>Es öffnet sich anschließend ein Dateiexplorer, in dem du den gewünschten Speicherort auswählen kannst.',
"hp_createDoc_p" : '- Öffne oben links das Burgermenü und wähle den Punkt <strong>„Dokumententypen verwalten“</strong>.<br>- Wähle anschließend im Auswahlmenü die Option <strong>„-- Neuen Dokumententyp erstellen --“</strong>.<br>- Vergib einen aussagekräftigen Namen für den neuen Dokumententyp.<br>- Formuliere den Prompt für die KI-gestützte Verarbeitung sorgfältig.<br>- Klicke auf <strong>Dokumententyp speichern</strong>.<br><br><strong>Hinweis:</strong> <br>Der eingegebene Prompt wird unverändert an einen KI-Dienst übermittelt. Achte daher unbedingt auf die Einhaltung der geltenden Datenschutzrichtlinien und gib keine sensiblen oder personenbezogenen Daten ein.',
"hp_editDoc_p" : '- Öffne oben links das Burgermenü und wähle den Punkt <strong>„Dokumententypen verwalten“</strong>.<br>- Wähle anschließend im Auswahlmenü den zu bearbeitenden Dokumententyp aus.<br>- Überarbeite den bestehenden KI-Prompt oder formuliere einen neuen Prompt.<br>- Klicke abschließend auf <strong>„Dokumententyp speichern“</strong>.<br><br><strong>Hinweis:</strong><br>Der eingegebene Prompt wird unverändert an einen KI-Dienst übermittelt. Achte daher unbedingt auf die Einhaltung der geltenden Datenschutzrichtlinien und gib keine sensiblen oder personenbezogenen Daten ein.',
"hp_deleteDoc_p" : '- Öffne oben links das Burgermenü und wähle den Punkt <strong>„Dokumententypen verwalten“</strong>.<br>- Wähle anschließend im Auswahlmenü den zu löschenden Dokumententyp aus.<br>- Klicke abschließend auf <strong>„Dokumententyp löschen“</strong>.<br><br><strong>Hinweis:</strong><br>Nach Bestätigung des Löschvorgangs kann der Dokumententyp nicht wiederhergestellt werden.'
}, },
"in":{ "in":{
"flagPath": "flags/india-flag-png-large.png", "flagPath": "flags/india-flag-png-large.png",
"labelKI": "की का चयन करें:", "labelKI": "KI का चयन करें:",
"labelTranscription": "प्रतिलेखन चुनें:", "labelTranscription": "प्रतिलेखन चुनें:",
"labelLanguage": "भाषा चुने:", "labelLanguage": "भाषा चुने:",
"title": "दस्तावेज़ के लिए वीडियो", "title": "दस्तावेज़ के लिए वीडियो",
"h1": "दस्तावेज़ के लिए वीडियो", "h1": "दस्तावेज़ के लिए वीडियो",
"p1": "वीडियो फ़ाइल खींचें और छोड़ें", "p1": "वीडियो फ़ाइल खींचें और छोड़ें",
"fileName": "कोई वीडियो नहीं चुना गया", "fileName": "कोई वीडियो नहीं चुना गया",
"manualUploadBtn": "वीडियो खोजें", "manualUploadBtn": "वीडियो खोजें",
"checkbox_group": "पसंदीदा दस्तावेज़ शैली चुनें:", "checkbox_group": "पसंदीदा दस्तावेज़ शैली चुनें:",
"label_format": "बैठक रिपोर्ट", "label_format": "अनुवर्ती रिपोर्ट",
"label_summary": "टाइमस्टैम्प के साथ सारांश", "label_summary": "कार्यसूची",
"submitButton": "जमा करना", "label_summary_result": "परिणाम प्रोटोकॉल",
"label_summary_note" : "स्प्रिंट योजना नोट",
"submitButton": "जमा करें",
"step_nav1": "स्टेप 1", "step_nav1": "स्टेप 1",
"step_nav2": "स्टेप 2", "step_nav2": "स्टेप 2",
"step_nav3": "स्टेप 3", "step_nav3": "स्टेप 3",
@@ -110,11 +206,11 @@ var languageOptions = {
"step_nav6": "स्टेप 6", "step_nav6": "स्टेप 6",
"h2": "अपना वीडियो यहां अपलोड करें:", "h2": "अपना वीडियो यहां अपलोड करें:",
"labelSpeaker": "स्पीकर चुनें:", "labelSpeaker": "स्पीकर चुनें:",
"labelSpeakerAudio": "चयनित वक्ता:", "labelSpeakerAudio": "चयनित स्पीकर:",
"labelSpeakerWriter": "नाम लिखें:", "labelSpeakerWriter": "नाम लिखें:",
"speakerLocker": "स्पीकर का नाम बदलें", "speakerLocker": "स्पीकर का नाम बदलें",
"speakerResender": "दस्तावेज़ पुनः लिखें", "speakerResender": "दस्तावेज़ फिर से लिखें",
"downloadButton": "डाउनलोड करना", "downloadButton": "डाउनलोड करें",
"box1_p1": "---प्रारंभ---", "box1_p1": "---प्रारंभ---",
"box2_p2": "---प्रतिलेखन---", "box2_p2": "---प्रतिलेखन---",
"box3_p3": "---दस्तावेज़ निर्माण---", "box3_p3": "---दस्तावेज़ निर्माण---",
@@ -127,11 +223,229 @@ var languageOptions = {
"docName": "यहां दस्तावेज़ का नाम दर्ज करें", "docName": "यहां दस्तावेज़ का नाम दर्ज करें",
"cd_promt": "आपका संकेत:", "cd_promt": "आपका संकेत:",
"prompt": "अपने दस्तावेज़ के लिए प्रॉम्प्ट यहां टाइप करें...", "prompt": "अपने दस्तावेज़ के लिए प्रॉम्प्ट यहां टाइप करें...",
"goBackBtn": "वापस करना", "goBackBtn": "वापस जाएं",
"deleteBtn": "दस्तावेज़ हटाए", "deleteBtn": "दस्तावेज़ हटाए",
"generateBtn": "दस्तावेज़ सहेजें", "generateBtn": "दस्तावेज़ सहेजें",
"newDoc": "-- नया दस्तावेज़ बनाए --" "newDoc": "-- नया दस्तावेज़ बनाए --",
"step1_h2" : "अपना वीडियो यहां अपलोड करें:",
"step2_h2" : "अपनी प्राथमिकताएँ चुनें:",
"step3_h2" : "पसंदीदा दस्तावेज़ शैली चुनें:",
"step4_h2" : "सबमिट करने के लिए क्लिक करें:",
"step5_h2" : "वक्ताओं के नाम बदलें:",
"step6_h2" : "अपना दस्तावेज़ डाउनलोड करने के लिए यहां क्लिक करें:",
//help page
"back_btn" : "पीछे",
"help_page_h1" : "प्रोग्राम ट्यूटोरियल",
"help_page_tableofcontents" : "विषयसूची",
//Inhaltsverzeichnis
"hp_convertVid" : "वीडियो को दस्तावेज़ में बदलें",
"hp_firstStep" : "चरण 1 - वीडियो चुनें",
"hp_secondStep" : "चरण 2 - कॉन्फ़िगरेशन",
"hp_thirdStep" : "चरण 3 - दस्तावेज़ प्रकार चुनें",
"hp_fourthStep" : "चरण 4 - पुष्टि करें",
"hp_fifthStep" : "चरण 5 - वक्ताओं की पहचान करें",
"hp_sixthStep" : "चरण 6 - दस्तावेज़ सहेजें",
"hp_createDoc" : "दस्तावेज़ प्रकार बनाएँ",
"hp_editDoc" : "दस्तावेज़ प्रकार संपादित करें",
"hp_deleteDoc" : "दस्तावेज़ प्रकार हटाएँ",
//Ueberschriften
"hp_convertVid_h2" : "वीडियो को दस्तावेज़ में बदलें.",
"hp_firstStep_h3" : "चरण 1 - वीडियो चुनें",
"hp_secondStep_h3" : "चरण 2 - कॉन्फ़िगरेशन",
"hp_thirdStep_h3" : "चरण 3 - दस्तावेज़ प्रकार चुनें",
"hp_fourthStep_h3" : "चरण 4 - पुष्टि करें",
"hp_fifthStep_h3" : "चरण 5 - वक्ताओं की पहचान करें",
"hp_sixthStep_h3" : "चरण 6 - दस्तावेज़ सहेजें",
"hp_createDoc_h2" : "दस्तावेज़ प्रकार बनाएँ",
"hp_editDoc_h2" : "दस्तावेज़ प्रकार संपादित करें",
"hp_deleteDoc_h2" : "दस्तावेज़ प्रकार हटाएँ",
//Texte
"hp_firstStep_p" : "- किसी वीडियो फ़ाइल को ड्रैग-एंड-ड्रॉप फ़ील्ड में डालें या <strong>“वीडियो खोजें”</strong> पर क्लिक करें,<br>ताकि आप फ़ाइल ब्राउज़र के माध्यम से फ़ाइल चुन सकें।<br>- फिर आगे बढ़ने के लिए <strong>चरण 2</strong> या दाईं ओर नीले तीर पर क्लिक करें।",
"hp_secondStep_p" : "- पहले ड्रॉपडाउन मेनू में उपयोग की जाने वाली <strong>AI</strong> चुनें।<br>- दूसरे ड्रॉपडाउन मेनू में उपयोग किया जाने वाला <strong>ट्रांसक्रिप्शन टूल</strong> चुनें।<br>- तीसरे ड्रॉपडाउन मेनू में बनाए जाने वाले दस्तावेज़ का <strong>फ़ाइल फ़ॉर्मेट</strong> चुनें।<br>- चौथे ड्रॉपडाउन मेनू में बनाए जाने वाले दस्तावेज़ की <strong>भाषा</strong> चुनें।<br>- फिर आगे बढ़ने के लिए <strong>चरण 3</strong> या दाईं ओर नीले तीर पर क्लिक करें।",
"hp_thirdStep_p" : "- चेकबॉक्स का उपयोग करके किसी दस्तावेज़ प्रकार का चयन करें या ड्रॉपडाउन मेनू से पहले से बनाए गए दस्तावेज़ प्रकार को चुनें।<br>- फिर आगे बढ़ने के लिए <strong>चरण 4</strong> या दाईं ओर नीले तीर पर क्लिक करें।",
"hp_fourthStep_p" : "<strong>“Submit”</strong> पर क्लिक करें ताकि दस्तावेज़ निर्माण शुरू हो सके।<br>प्रसंस्करण के दौरान चार स्थिति संकेतक दिखाए जाते हैं, जो धीरे-धीरे लाल से हरे रंग में बदलते हैं और वर्तमान प्रगति दर्शाते हैं:<br><br>संकेतक 1: वीडियो फ़ाइल का अपलोड और तैयारी।<br>संकेतक 2: वीडियो सामग्री का ट्रांसक्रिप्शन।<br>संकेतक 3: AI-आधारित प्रसंस्करण और दस्तावेज़ निर्माण।<br>संकेतक 4: निर्माण का समापन और दस्तावेज़ की उपलब्धता।<br><br>सफलतापूर्वक पूरा होने के बाद, आगे बढ़ने के लिए <strong>चरण 5</strong> या दाईं ओर नीले तीर पर क्लिक करें।",
"hp_fifthStep_p" : "ड्रॉपडाउन मेनू में आप किसी पहचाने गए वक्ता का चयन कर सकते हैं।<br>प्ले बटन का उपयोग करके आप किसी बोले गए वाक्य को सुन सकते हैं ताकि वक्ता की स्पष्ट पहचान हो सके।<br>स्पीकर आइकन से आप वॉल्यूम समायोजित कर सकते हैं।<br>तीन-डॉट मेनू से आप प्लेबैक गति सेट कर सकते हैं।<br><br>टेक्स्ट फ़ील्ड <strong>“Write name”</strong> में वक्ता का वास्तविक नाम दर्ज करें ताकि दस्तावेज़ में “Speaker A” जैसे प्लेसहोल्डर के बजाय वही नाम दिखाया जाए।<br><strong>“Rename Speaker”</strong> के साथ प्रविष्टि की पुष्टि करें।<br><br><strong>“Rewrite Document”</strong> बटन से दस्तावेज़ में सभी वक्ता नामों को बदल दिया जाता है।<br><br>इसके बाद आगे बढ़ने के लिए <strong>चरण 6</strong> या दाईं ओर नीले तीर पर क्लिक करें।",
"hp_sixthStep_p" : "<strong>“Download”</strong> पर क्लिक करें ताकि दस्तावेज़ सहेजा जा सके।<br>इसके बाद एक फ़ाइल एक्सप्लोरर खुलेगा, जहाँ आप इच्छित संग्रह स्थान चुन सकते हैं।",
"hp_createDoc_p" : "- ऊपर बाएँ कोने में बर्गर मेनू खोलें और <strong>“दस्तावेज़ प्रकार प्रबंधित करें”</strong> चुनें।<br>- फिर ड्रॉपडाउन मेनू से <strong>“-- नया दस्तावेज़ प्रकार बनाएँ --”</strong> विकल्प चुनें।<br>- नए दस्तावेज़ प्रकार के लिए एक अर्थपूर्ण नाम दर्ज करें।<br>- AI-आधारित प्रसंस्करण के लिए प्रॉम्प्ट को सावधानीपूर्वक तैयार करें।<br>- <strong>दस्तावेज़ प्रकार सहेजें</strong> पर क्लिक करें।<br><br><strong>नोट:</strong><br>दर्ज किया गया प्रॉम्प्ट बिना किसी बदलाव के एक AI सेवा को भेजा जाता है। इसलिए लागू डेटा संरक्षण नियमों का पालन करें और कोई संवेदनशील या व्यक्तिगत डेटा दर्ज न करें।",
"hp_editDoc_p" : "- ऊपर बाएँ कोने में बर्गर मेनू खोलें और <strong>“दस्तावेज़ प्रकार प्रबंधित करें”</strong> चुनें।<br>- फिर ड्रॉपडाउन मेनू से संपादित किए जाने वाले दस्तावेज़ प्रकार को चुनें।<br>- मौजूदा AI प्रॉम्प्ट को संशोधित करें या नया प्रॉम्प्ट तैयार करें।<br>- अंत में <strong>“दस्तावेज़ प्रकार सहेजें”</strong> पर क्लिक करें।<br><br><strong>नोट:</strong><br>दर्ज किया गया प्रॉम्प्ट बिना किसी बदलाव के एक AI सेवा को भेजा जाता है। इसलिए लागू डेटा संरक्षण नियमों का पालन करें और कोई संवेदनशील या व्यक्तिगत डेटा दर्ज न करें।",
"hp_deleteDoc_p" : "- ऊपर बाएँ कोने में बर्गर मेनू खोलें और <strong>“दस्तावेज़ प्रकार प्रबंधित करें”</strong> चुनें।<br>- फिर ड्रॉपडाउन मेनू से हटाए जाने वाले दस्तावेज़ प्रकार को चुनें।<br>- अंत में <strong>“दस्तावेज़ प्रकार हटाएँ”</strong> पर क्लिक करें।<br><br><strong>नोट:</strong><br>हटाने की प्रक्रिया की पुष्टि करने के बाद, दस्तावेज़ प्रकार को पुनर्स्थापित नहीं किया जा सकता।"
}/*,
"cz":{
"flagPath": "flags/czechia-flag-png-large.png",
"labelKI": "Vyberte AI:",
"labelTranscription": "Vyberte přepis:",
"labelLanguage": "Vyberte jazyk:",
"title": "Video na dokument",
"h1": "Video na dokument",
"p1": "Přetáhněte video pomocí Drag & Drop",
"fileName": "Nebylo vybráno žádné video",
"manualUploadBtn": "Vyhledat video",
"checkbox_group": "Preferované varianty dokumentu:",
"label_format": "Zpráva ze schůzky",
"label_summary": "Shrnutí s časovými značkami",
"submitButton": "Odeslat",
"step_nav1": "Krok 1",
"step_nav2": "Krok 2",
"step_nav3": "Krok 3",
"step_nav4": "Krok 4",
"step_nav5": "Krok 5",
"step_nav6": "Krok 6",
"h2": "Nahrajte své video zde:",
"labelSpeaker": "Vyberte mluvčího:",
"labelSpeakerAudio": "Vybraný mluvčí:",
"labelSpeakerWriter": "Zadejte jméno:",
"speakerLocker": "Nahradit jména",
"speakerResender": "Přepsat dokument",
"downloadButton": "Stáhnout",
"box1_p1": "---Spouští se---",
"box2_p2": "---Přepis---",
"box3_p3": "---Vytváření dokumentu---",
"labelType": "Vyberte typ dokumentu:",
"customDocBtn": "Spravovat typy dokumentů",
"cd_h1": "Spravovat typy dokumentů",
"cd_existingDocs": "Vybrat existující dokumenty (volitelné):",
"cd_docName": "Název dokumentu",
"docName": "Zadejte zde název dokumentu",
"cd_promt": "Váš prompt:",
"prompt": "Zadejte zde pokyn pro váš dokument...",
"goBackBtn": "Zpět",
"deleteBtn": "Smazat dokument",
"generateBtn": "Uložit dokument",
"newDoc": "-- Vytvořit nový dokument --",
"step1_h2" : "Nahrajte své video zde:",
"step2_h2" : "Vyberte své preference:",
"step3_h2" : "Vyberte požadovaný styl dokumentu:",
"step4_h2" : "Klikněte pro odeslání:",
"step5_h2" : "Změňte jména mluvčích:",
"step6_h2" : "Klikněte zde pro stažení dokumentu:",
//help page
//Inhaltsverzeichnis
"hp_convertVid" : "Převést video na dokument",
"hp_firstStep" : "Krok 1 - Vybrat video",
"hp_secondStep" : "Krok 2 - Konfigurace",
"hp_thirdStep" : "Krok 3 - Vybrat typ dokumentu",
"hp_fourthStep" : "Krok 4 - Potvrdit",
"hp_fifthStep" : "Krok 5 - Identifikovat mluvčí",
"hp_sixthStep" : "Krok 6 - Uložit dokument",
"hp_createDoc" : "Vytvořit typ dokumentu",
"hp_editDoc" : "Upravit typ dokumentu",
"hp_deleteDoc" : "Smazat typ dokumentu",
//Ueberschriften
"hp_convertVid_h2" : "Převést video na dokument.",
"hp_firstStep_h3" : "Krok 1 - Vybrat video",
"hp_secondStep_h3" : "Krok 2 - Konfigurace",
"hp_thirdStep_h3" : "Krok 3 - Vybrat typ dokumentu",
"hp_fourthStep_h3" : "Krok 4 - Potvrdit",
"hp_fifthStep_h3" : "Krok 5 - Identifikovat mluvčí",
"hp_sixthStep_h3" : "Krok 6 - Uložit dokument",
"hp_createDoc_h2" : "Vytvořit typ dokumentu",
"hp_editDoc_h2" : "Upravit typ dokumentu",
"hp_deleteDoc_h2" : "Smazat typ dokumentu",
//Texte
"hp_firstStep_p" : "- Přetáhněte video soubor do pole drag-and-drop nebo klikněte na <strong>„Vyhledat video“</strong>,<br>abyste vybrali soubor pomocí prohlížeče souborů.<br>- Poté klikněte na <strong>Krok 2</strong> nebo na modrou šipku vpravo pro pokračování.",
"hp_secondStep_p" : "- V prvním rozbalovacím menu vyberte používanou <strong>AI</strong>.<br>- Ve druhém rozbalovacím menu vyberte používaný <strong>nástroj pro přepis</strong>.<br>- Ve třetím rozbalovacím menu vyberte <strong>formát souboru</strong> vytvářeného dokumentu.<br>- Ve čtvrtém rozbalovacím menu vyberte <strong>jazyk</strong> vytvářeného dokumentu.<br>- Poté klikněte na <strong>Krok 3</strong> nebo na modrou šipku vpravo pro pokračování.",
"hp_thirdStep_p" : "- Vyberte typ dokumentu pomocí zaškrtávacího políčka nebo vyberte dříve vytvořený typ dokumentu z rozbalovacího menu.<br>- Poté klikněte na <strong>Krok 4</strong> nebo na modrou šipku vpravo pro pokračování.",
"hp_fourthStep_p" : "Klikněte na <strong>„Submit“</strong> pro zahájení generování dokumentu.<br>Během zpracování se zobrazují čtyři stavové indikátory, které se postupně mění z červené na zelenou a zobrazují aktuální průběh:<br><br>Indikátor 1: Nahrání a příprava video souboru.<br>Indikátor 2: Přepis obsahu videa.<br>Indikátor 3: Zpracování pomocí AI a vytvoření dokumentu.<br>Indikátor 4: Dokončení generování a zpřístupnění dokumentu.<br><br>Po úspěšném dokončení klikněte na <strong>Krok 5</strong> nebo na modrou šipku vpravo pro pokračování.",
"hp_fifthStep_p" : "V rozbalovacím menu můžete vybrat rozpoznaného mluvčího.<br>Pomocí tlačítka přehrávání si můžete poslechnout mluvenou větu pro jednoznačnou identifikaci mluvčího.<br>Pomocí ikony reproduktoru můžete upravit hlasitost.<br>Pomocí menu se třemi tečkami můžete nastavit rychlost přehrávání.<br><br>Do textového pole <strong>„Write name“</strong> zadejte skutečné jméno mluvčího, aby se v dokumentu zobrazovalo místo zástupných názvů jako „Speaker A“.<br>Potvrďte zadání pomocí <strong>„Rename Speaker“</strong>.<br><br>Tlačítkem <strong>„Rewrite Document“</strong> se následně nahradí všechna označení mluvčích v dokumentu.<br><br>Poté klikněte na <strong>Krok 6</strong> nebo na modrou šipku vpravo pro pokračování.",
"hp_sixthStep_p" : "Klikněte na <strong>„Download“</strong> pro uložení dokumentu.<br>Následně se otevře průzkumník souborů, kde můžete vybrat požadované umístění.",
"hp_createDoc_p" : "- Otevřete hamburger menu vlevo nahoře a vyberte položku <strong>„Spravovat typy dokumentů“</strong>.<br>- Poté v rozbalovacím menu vyberte možnost <strong>„-- Vytvořit nový typ dokumentu --“</strong>.<br>- Zadejte výstižný název pro nový typ dokumentu.<br>- Pečlivě formulujte prompt pro zpracování pomocí AI.<br>- Klikněte na <strong>Uložit typ dokumentu</strong>.<br><br><strong>Poznámka:</strong><br>Zadaný prompt je beze změny odeslán službě AI. Dbejte proto na dodržování platných předpisů o ochraně osobních údajů a nezadávejte žádná citlivá ani osobní data.",
"hp_editDoc_p" : "- Otevřete hamburger menu vlevo nahoře a vyberte položku <strong>„Spravovat typy dokumentů“</strong>.<br>- Poté v rozbalovacím menu vyberte typ dokumentu, který chcete upravit.<br>- Upravte stávající AI prompt nebo vytvořte nový prompt.<br>- Nakonec klikněte na <strong>„Uložit typ dokumentu“</strong>.<br><br><strong>Poznámka:</strong><br>Zadaný prompt je beze změny odeslán službě AI. Dbejte proto na dodržování platných předpisů o ochraně osobních údajů a nezadávejte žádná citlivá ani osobní data.",
"hp_deleteDoc_p" : "- Otevřete hamburger menu vlevo nahoře a vyberte položku <strong>„Spravovat typy dokumentů“</strong>.<br>- Poté v rozbalovacím menu vyberte typ dokumentu, který chcete smazat.<br>- Nakonec klikněte na <strong>„Smazat typ dokumentu“</strong>.<br><br><strong>Poznámka:</strong><br>Po potvrzení procesu smazání nelze typ dokumentu obnovit."
},
"ru":{
"flagPath": "flags/russia-flag-png-large.png",
"labelKI": "Выберите ИИ:",
"labelTranscription": "Выберите транскрипцию:",
"labelLanguage": "Выберите язык:",
"title": "Видео в документ",
"h1": "Видео в документ",
"p1": "Перетащите видео с помощью Drag & Drop",
"fileName": "Видео не выбрано",
"manualUploadBtn": "Найти видео",
"checkbox_group": "Предпочтительные варианты документа:",
"label_format": "Отчет о встрече",
"label_summary": "Резюме с временными метками",
"submitButton": "Отправить",
"step_nav1": "Шаг 1",
"step_nav2": "Шаг 2",
"step_nav3": "Шаг 3",
"step_nav4": "Шаг 4",
"step_nav5": "Шаг 5",
"step_nav6": "Шаг 6",
"h2": "Загрузите ваше видео здесь:",
"labelSpeaker": "Выберите говорящего:",
"labelSpeakerAudio": "Выбранный говорящий:",
"labelSpeakerWriter": "Введите имя:",
"speakerLocker": "Заменить имена",
"speakerResender": "Перезаписать документ",
"downloadButton": "Скачать",
"box1_p1": "---Запуск---",
"box2_p2": "---Транскрибация---",
"box3_p3": "---Создание документа---",
"labelType": "Выберите тип документа:",
"customDocBtn": "Управление типами документов",
"cd_h1": "Управление типами документов",
"cd_existingDocs": "Выбрать существующие документы (необязательно):",
"cd_docName": "Название документа",
"docName": "Введите здесь название документа",
"cd_promt": "Ваш запрос:",
"prompt": "Введите здесь запрос для вашего документа...",
"goBackBtn": "Назад",
"deleteBtn": "Удалить документ",
"generateBtn": "Сохранить документ",
"newDoc": "-- Создать новый документ --",
"step1_h2" : "Загрузите ваше видео здесь:",
"step2_h2" : "Выберите ваши предпочтения:",
"step3_h2" : "Выберите желаемый стиль документа:",
"step4_h2" : "Нажмите для отправки:",
"step5_h2" : "Измените имена говорящих:",
"step6_h2" : "Нажмите здесь, чтобы скачать документ:",
//help page
//Inhaltsverzeichnis
"hp_convertVid" : "Преобразовать видео в документ",
"hp_firstStep" : "Шаг 1 - Выбрать видео",
"hp_secondStep" : "Шаг 2 - Конфигурация",
"hp_thirdStep" : "Шаг 3 - Выбрать тип документа",
"hp_fourthStep" : "Шаг 4 - Подтвердить",
"hp_fifthStep" : "Шаг 5 - Идентифицировать говорящих",
"hp_sixthStep" : "Шаг 6 - Сохранить документ",
"hp_createDoc" : "Создать тип документа",
"hp_editDoc" : "Редактировать тип документа",
"hp_deleteDoc" : "Удалить тип документа",
//Ueberschriften
"hp_convertVid_h2" : "Преобразовать видео в документ.",
"hp_firstStep_h3" : "Шаг 1 - Выбрать видео",
"hp_secondStep_h3" : "Шаг 2 - Конфигурация",
"hp_thirdStep_h3" : "Шаг 3 - Выбрать тип документа",
"hp_fourthStep_h3" : "Шаг 4 - Подтвердить",
"hp_fifthStep_h3" : "Шаг 5 - Идентифицировать говорящих",
"hp_sixthStep_h3" : "Шаг 6 - Сохранить документ",
"hp_createDoc_h2" : "Создать тип документа",
"hp_editDoc_h2" : "Редактировать тип документа",
"hp_deleteDoc_h2" : "Удалить тип документа",
//Texte
"hp_firstStep_p" : "- Перетащите видеофайл в поле drag-and-drop или нажмите <strong>«Найти видео»</strong>,<br>чтобы выбрать файл через файловый браузер.<br>- Затем нажмите <strong>Шаг 2</strong> или синюю стрелку справа, чтобы продолжить.",
"hp_secondStep_p" : "- В первом выпадающем меню выберите используемый <strong>ИИ</strong>.<br>- Во втором выпадающем меню выберите используемый <strong>инструмент транскрипции</strong>.<br>- В третьем выпадающем меню выберите <strong>формат файла</strong> создаваемого документа.<br>- В четвертом выпадающем меню выберите <strong>язык</strong> создаваемого документа.<br>- Затем нажмите <strong>Шаг 3</strong> или синюю стрелку справа, чтобы продолжить.",
"hp_thirdStep_p" : "- Выберите тип документа с помощью флажка или выберите ранее созданный тип документа из выпадающего меню.<br>- Затем нажмите <strong>Шаг 4</strong> или синюю стрелку справа, чтобы продолжить.",
"hp_fourthStep_p" : "Нажмите <strong>«Submit»</strong>, чтобы начать генерацию документа.<br>Во время обработки отображаются четыре индикатора состояния, которые постепенно меняют цвет с красного на зеленый и показывают текущий прогресс:<br><br>Индикатор 1: Загрузка и подготовка видеофайла.<br>Индикатор 2: Транскрибация содержимого видео.<br>Индикатор 3: Обработка с помощью ИИ и создание документа.<br>Индикатор 4: Завершение генерации и предоставление документа.<br><br>После успешного завершения нажмите <strong>Шаг 5</strong> или синюю стрелку справа, чтобы продолжить.",
"hp_fifthStep_p" : "В выпадающем меню вы можете выбрать распознанного говорящего.<br>С помощью кнопки воспроизведения можно прослушать произнесенное предложение, чтобы однозначно идентифицировать говорящего.<br>С помощью значка динамика можно отрегулировать громкость.<br>С помощью меню с тремя точками можно установить скорость воспроизведения.<br><br>В текстовом поле <strong>«Write name»</strong> введите настоящее имя говорящего, чтобы в документе оно отображалось вместо заполнителей, таких как «Speaker A».<br>Подтвердите ввод с помощью <strong>«Rename Speaker»</strong>.<br><br>Кнопкой <strong>«Rewrite Document»</strong> затем заменяются все обозначения говорящих в документе.<br><br>После этого нажмите <strong>Шаг 6</strong> или синюю стрелку справа, чтобы продолжить.",
"hp_sixthStep_p" : "Нажмите <strong>«Download»</strong>, чтобы сохранить документ.<br>Затем откроется файловый проводник, в котором вы можете выбрать желаемое место сохранения.",
"hp_createDoc_p" : "- Откройте меню-бургер в левом верхнем углу и выберите пункт <strong>«Управление типами документов»</strong>.<br>- Затем в выпадающем меню выберите опцию <strong>«-- Создать новый тип документа --»</strong>.<br>- Введите понятное название для нового типа документа.<br>- Тщательно сформулируйте запрос для обработки с помощью ИИ.<br>- Нажмите <strong>Сохранить тип документа</strong>.<br><br><strong>Примечание:</strong><br>Введенный запрос без изменений передается службе ИИ. Поэтому обязательно соблюдайте действующие правила защиты данных и не вводите никакие чувствительные или персональные данные.",
"hp_editDoc_p" : "- Откройте меню-бургер в левом верхнем углу и выберите пункт <strong>«Управление типами документов»</strong>.<br>- Затем в выпадающем меню выберите тип документа для редактирования.<br>- Измените существующий запрос ИИ или сформулируйте новый запрос.<br>- В конце нажмите <strong>«Сохранить тип документа»</strong>.<br><br><strong>Примечание:</strong><br>Введенный запрос без изменений передается службе ИИ. Поэтому обязательно соблюдайте действующие правила защиты данных и не вводите никакие чувствительные или персональные данные.",
"hp_deleteDoc_p" : "- Откройте меню-бургер в левом верхнем углу и выберите пункт <strong>«Управление типами документов»</strong>.<br>- Затем в выпадающем меню выберите тип документа для удаления.<br>- В конце нажмите <strong>«Удалить тип документа»</strong>.<br><br><strong>Примечание:</strong><br>После подтверждения процесса удаления тип документа не может быть восстановлен."
} }
*/
}; };
-44
View File
@@ -1,44 +0,0 @@
import { app, BrowserWindow, ipcMain, dialog } from 'electron';
import { exec } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
}
});
mainWindow.loadFile('main/index.html');
}
app.whenReady().then(createWindow);
// Kommunikation vom Renderer (Frontend)
ipcMain.handle('convert-video', async (event, filePath) => {
const output = path.join(path.dirname(filePath), 'converted.mp4');
return new Promise((resolve, reject) => {
exec(`ffmpeg -i "${filePath}" -vcodec libx264 "${output}"`, (error, stdout, stderr) => {
if (error) {
console.error('Fehler beim Konvertieren:', error);
reject(error);
} else {
console.log('Konvertierung abgeschlossen:', output);
resolve(output);
}
});
});
});
+12 -4
View File
@@ -1,31 +1,39 @@
/*
This file contains the ipc communication methos between the ui and the gui
*/
const { contextBridge, ipcRenderer, webUtils } = require('electron') const { contextBridge, ipcRenderer, webUtils } = require('electron')
try { try {
//For file lookup on drop
contextBridge.exposeInMainWorld("explorer", { contextBridge.exposeInMainWorld("explorer", {
onFileDrop: (file) => webUtils.getPathForFile(file) onFileDrop: (file) => webUtils.getPathForFile(file)
}) })
//For sending the specifications to the main
contextBridge.exposeInMainWorld("submit", { contextBridge.exposeInMainWorld("submit", {
submit: (meeting_specifications) => { ipcRenderer.send("file_submit", meeting_specifications) } submit: (meeting_specifications) => { ipcRenderer.send("file_submit", meeting_specifications) }
}) })
//For file lookup on search
contextBridge.exposeInMainWorld("electronAPI", { contextBridge.exposeInMainWorld("electronAPI", {
getFilePath: (file) => { return webUtils.getPathForFile(file) } getFilePath: (file) => { return webUtils.getPathForFile(file) }
}) })
//Gets all information from the main process
contextBridge.exposeInMainWorld("onStartup", { contextBridge.exposeInMainWorld("onStartup", {
getModuleNames: () => ipcRenderer.invoke('get-module-names') getModuleNames: () => ipcRenderer.invoke('get-module-names')
}) })
//Calls from the main process regarding the progress
contextBridge.exposeInMainWorld('electron', { contextBridge.exposeInMainWorld('electron', {
progress: (callback) => ipcRenderer.on('progress', callback) progress: (callback) => ipcRenderer.on('progress', callback)
}) })
//For getting the speaker audios and names from the main
contextBridge.exposeInMainWorld('audios', { contextBridge.exposeInMainWorld('audios', {
speakerAudios: (callback) => ipcRenderer.on('speakerAudios', callback) speakerAudios: (callback) => ipcRenderer.on('speakerAudios', callback)
}) })
//For sending the new speaker names to the main process
contextBridge.exposeInMainWorld("submitSpeaker", { contextBridge.exposeInMainWorld("submitSpeaker", {
speaker_submit: (speaker_names) => { ipcRenderer.send("speaker_submit", speaker_names) } speaker_submit: (speaker_names) => { ipcRenderer.send("speaker_submit", speaker_names) }
}) })
//For downloading the finished document
contextBridge.exposeInMainWorld("download", { contextBridge.exposeInMainWorld("download", {
file_download: () => { ipcRenderer.send("file_download") } file_download: () => { ipcRenderer.send("file_download") }
}) })
+83 -62
View File
@@ -27,7 +27,6 @@ language_option.addEventListener('change', (e) => {
console.log("Error in the language_option change listener in the renderer.js"); console.log("Error in the language_option change listener in the renderer.js");
console.log(error); console.log(error);
} }
}); });
stepButtons.forEach(btn => { stepButtons.forEach(btn => {
@@ -36,7 +35,7 @@ stepButtons.forEach(btn => {
const step = parseInt(btn.dataset.step); const step = parseInt(btn.dataset.step);
showStep(step); showStep(step);
} catch (error) { } catch (error) {
console.log(error);
} }
}); });
}); });
@@ -46,7 +45,7 @@ prevBtn.addEventListener("click", () => {
try { try {
if (currentStep > 1) showStep(currentStep - 1); if (currentStep > 1) showStep(currentStep - 1);
} catch (error) { } catch (error) {
console.log(error);
} }
}); });
@@ -55,7 +54,7 @@ nextBtn.addEventListener("click", () => {
try { try {
if (currentStep < totalSteps) showStep(currentStep + 1); if (currentStep < totalSteps) showStep(currentStep + 1);
} catch (error) { } catch (error) {
console.log(error);
} }
}); });
@@ -73,7 +72,6 @@ uploadContainer.addEventListener("dragover", (e) => {
} catch (error) { } catch (error) {
console.log("Error in renderer.js dragover listener function") console.log("Error in renderer.js dragover listener function")
} }
}); });
//listener for when a file get dropped on the drag&drop field //listener for when a file get dropped on the drag&drop field
@@ -91,12 +89,11 @@ uploadContainer.addEventListener("drop", (e) => {
} else { } else {
alert('The given file is not compatible. These are the available types: [".mp4", ".mov", ".avi", ".mkv"].'); alert('The given file is not compatible. These are the available types: [".mp4", ".mov", ".avi", ".mkv"].');
} }
} catch (error) { } catch (error) {
console.log("Error in renderer.js with the listerner for the drop function"); console.log("Error in renderer.js with the listerner for the drop function");
console.log(error); console.log(error);
} }
}) });
//listener for the file explorer search when something got selected //listener for the file explorer search when something got selected
videoUpload.addEventListener("change", () => { videoUpload.addEventListener("change", () => {
@@ -133,24 +130,7 @@ Listeners for Step 3
*/ */
window.api.getTxtFiles().then(files => { //Checkboxlistener so that only one checkbox can be selected at a time
var menu = document.getElementById('customDocumentTypes');
var l = document.getElementById('customDocumentTypes').options.length - 1;
for (i = l; i >= 0; i--) {
menu.remove(i);
}
files.forEach(file => {
const option = document.createElement('option');
option.value = file;
option.textContent = file
.replace('.txt', '') // Endung entfernen
.replace(/_/g, ' ') // Leerzeichen ersetzen
.replace(/\b\w/g, c => c.toUpperCase()) // ersten Buchstaben groß
menu.appendChild(option);
});
});
//Checkboxlistener so that only one can be selected at a time
docFormat.addEventListener("change", (e) => { docFormat.addEventListener("change", (e) => {
try { try {
if (docFormat.checked) { if (docFormat.checked) {
@@ -160,9 +140,10 @@ docFormat.addEventListener("change", (e) => {
docFormatCustom.checked = false; docFormatCustom.checked = false;
} }
} catch (error) { } catch (error) {
console.log(error)
} }
}); });
//Checkboxlistener so that only one checkbox can be selected at a time
docFormatSummary1.addEventListener("change", (e) => { docFormatSummary1.addEventListener("change", (e) => {
try { try {
if (docFormatSummary1.checked) { if (docFormatSummary1.checked) {
@@ -172,9 +153,10 @@ docFormatSummary1.addEventListener("change", (e) => {
docFormatCustom.checked = false; docFormatCustom.checked = false;
} }
} catch (error) { } catch (error) {
console.log(error)
} }
}); });
//Checkboxlistener so that only one checkbox can be selected at a time
docFormatSummary2.addEventListener("change", (e) => { docFormatSummary2.addEventListener("change", (e) => {
try { try {
if (docFormatSummary2.checked) { if (docFormatSummary2.checked) {
@@ -184,9 +166,10 @@ docFormatSummary2.addEventListener("change", (e) => {
docFormatCustom.checked = false; docFormatCustom.checked = false;
} }
} catch (error) { } catch (error) {
console.log(error)
} }
}); });
//Checkboxlistener so that only one checkbox can be selected at a time
docFormatSummary3.addEventListener("change", (e) => { docFormatSummary3.addEventListener("change", (e) => {
try { try {
if (docFormatSummary3.checked) { if (docFormatSummary3.checked) {
@@ -196,9 +179,10 @@ docFormatSummary3.addEventListener("change", (e) => {
docFormatCustom.checked = false; docFormatCustom.checked = false;
} }
} catch (error) { } catch (error) {
console.log(error)
} }
}); });
//Checkboxlistener so that only one checkbox can be selected at a time
docFormatCustom.addEventListener("change", (e) => { docFormatCustom.addEventListener("change", (e) => {
try { try {
if (docFormatCustom.checked) { if (docFormatCustom.checked) {
@@ -208,7 +192,7 @@ docFormatCustom.addEventListener("change", (e) => {
docFormat.checked = false; docFormat.checked = false;
} }
} catch (error) { } catch (error) {
console.log(error)
} }
}); });
@@ -217,8 +201,10 @@ docFormatCustom.addEventListener("change", (e) => {
Listeners for Step 4 Listeners for Step 4
*/ */
//Functions the the displayed progress in the progressbar can be changed out of the main process
//Functions for the displayed progress in the progressbar so it can be changed out of the main process
window.electron.progress((event, arg) => { window.electron.progress((event, arg) => {
try {
if (arg.curstep == 1) { if (arg.curstep == 1) {
setCircleOne(); setCircleOne();
} else if (arg.curstep == 2) { } else if (arg.curstep == 2) {
@@ -228,8 +214,12 @@ window.electron.progress((event, arg) => {
} else if (arg.curstep == 4) { } else if (arg.curstep == 4) {
setCircleFour(); setCircleFour();
} }
} catch (error) {
console.log(error)
}
}); });
//All for are for setting the corresponding progress section to green (or red)
function setCircleOne() { function setCircleOne() {
try { try {
if (document.getElementById("box1").style.backgroundColor == "green") { if (document.getElementById("box1").style.backgroundColor == "green") {
@@ -238,8 +228,8 @@ function setCircleOne() {
document.getElementById("box1").style.backgroundColor = "green"; document.getElementById("box1").style.backgroundColor = "green";
} }
} catch (error) { } catch (error) {
console.log(error)
} }
}; };
function setCircleZwo() { function setCircleZwo() {
try { try {
@@ -249,9 +239,8 @@ function setCircleZwo() {
document.getElementById("box2").style.backgroundColor = "green"; document.getElementById("box2").style.backgroundColor = "green";
} }
} catch (error) { } catch (error) {
console.log(error)
} }
}; };
function setCircleThree() { function setCircleThree() {
try { try {
@@ -261,9 +250,8 @@ function setCircleThree() {
document.getElementById("box3").style.backgroundColor = "green"; document.getElementById("box3").style.backgroundColor = "green";
} }
} catch (error) { } catch (error) {
console.log(error)
} }
}; };
function setCircleFour() { function setCircleFour() {
try { try {
@@ -273,7 +261,7 @@ function setCircleFour() {
document.getElementById("box4").style.backgroundColor = "green"; document.getElementById("box4").style.backgroundColor = "green";
} }
} catch (error) { } catch (error) {
console.log(error)
} }
}; };
@@ -283,39 +271,47 @@ Listeners for Step 5
*/ */
//Speaker change listener //Speaker change listener, changes the previewed audio snippet
cur_speaker.addEventListener("change", (e) => { cur_speaker.addEventListener("change", (e) => {
try { try {
document.getElementById("speakerAudioViewer").src = speakerAudios[document.getElementById("cur_speaker").value].src; document.getElementById("speakerAudioViewer").src = speakerAudios[document.getElementById("cur_speaker").value].src;
} catch (error) { } catch (error) {
console.log(error)
} }
}); });
//Function so the main process can give the gui a json with the speakers and their audio //Function so the main process can give the gui a json with the speakers and their audio
window.audios.speakerAudios((event, arg) => { window.audios.speakerAudios((event, arg) => {
try {
loadSpeakerOptions(arg); loadSpeakerOptions(arg);
setSpeakerAudiosValue(arg); setSpeakerAudiosValue(arg);
} catch (error) {
console.log(error)
}
}); });
/* /*
Listeners for the costum documents section Listeners for the costum documents section
*/ */
//Listener for closing the custom document section again
goBackBtn.addEventListener("click", () => { goBackBtn.addEventListener("click", () => {
try {
showCD(); showCD();
} catch (error) {
console.log(error)
}
}); });
// dokumente speichern //Listener for the save button in the custom document section
generateBtn.addEventListener("click", () => { generateBtn.addEventListener("click", () => {
try {
const name = docName.value.trim(); const name = docName.value.trim();
const content = document.getElementById("prompt").value.trim(); const content = document.getElementById("prompt").value.trim();
if (!name || !content) { if (!name || !content) {
result.textContent = "Bitte Dokumentname und Prompt ausfüllen."; result.textContent = "Bitte Dokumentname und Prompt ausfüllen.";
console.log(name + " " + content);
setTimeout(() => { setTimeout(() => {
result.textContent = ""; result.textContent = "";
}, 3000); }, 3000);
@@ -327,11 +323,14 @@ generateBtn.addEventListener("click", () => {
result.textContent = ""; result.textContent = "";
}, 3000); }, 3000);
reloadDocuments(); reloadDocuments();
} catch (error) {
console.log(error)
}
}); });
// dokumente löschen //Used for deleting documents in the costum document section
deleteBtn.addEventListener("click", () => { deleteBtn.addEventListener("click", () => {
try {
const name = docName.value.trim(); const name = docName.value.trim();
if (!name) { if (!name) {
@@ -341,51 +340,73 @@ deleteBtn.addEventListener("click", () => {
}, 3000); }, 3000);
return; return;
} }
var success = true;
const confirmDelete = confirm(
`Möchtest du das Dokument "${name}" wirklich löschen?`
);
if (!confirmDelete) return;
window.api.deleteTxtFile(name).then((success) => { window.api.deleteTxtFile(name).then((success) => {
if (success) { if (success) {
result.textContent = "Dokument erfolgreich gelöscht!"; result.textContent = "Dokument erfolgreich gelöscht!";
reloadDocuments(); reloadDocuments();
existingDocs.value = "newDoc";
existingDocs.dispatchEvent(new Event("change")); existingDocs.dispatchEvent(new Event("change"));
} else { } else {
result.textContent = "Dokument konnte nicht gelöscht werden."; result.textContent = "Dokument konnte nicht gelöscht werden.";
} }
setTimeout(() => {
result.textContent = "";
}, 3000);
}); });
} catch (error) {
console.log(error)
}
}); });
//function to load existingDoc options to the drop down list //function to load existingDoc options to the drop down list
window.api.getTxtFiles().then(files => { window.api.getTxtFiles().then(files => {
try {
reloadDocuments(); reloadDocuments();
} catch (error) {
console.log(error)
}
}); });
//content anzeigen //Shows the content inside the big textarea inside the costume dokument section
existingDocs.addEventListener("change", async () => { existingDocs.addEventListener("change", async () => {
try {
const existingDocsed = existingDocs.value; const existingDocsed = existingDocs.value;
const exampleText = ""; const exampleText = "";
if (existingDocsed === "newDoc") { if (existingDocsed === "newDoc") {
docNameWrapper.classList.remove("hidden"); docNameWrapper.classList.remove("hidden");
docName.value = ""; docName.value = "";
prompt.value = exampleText; document.getElementById("prompt").value = exampleText;
document.getElementById("prompt").textContent = exampleText;
return; return;
} }
docNameWrapper.classList.add("hidden"); docNameWrapper.classList.add("hidden");
document.getElementById("prompt").textContent = "";
document.getElementById("prompt").value = "";
const content = await window.api.readTxtFile(existingDocsed); const content = await window.api.readTxtFile(existingDocsed);
prompt.value = content; document.getElementById("prompt").value = content;
document.getElementById("prompt").textContent = content;
docName.value = existingDocsed.replace(".txt", ""); docName.value = existingDocsed.replace(".txt", "");
} catch (error) {
console.log(error)
}
}); });
/*
Listeners for the help page
*/
//For the help page dropdown list
document.addEventListener("click", function (e) {
try {
const toc = document.getElementById("toc");
const toggle = document.querySelector(".toc-toggle");
if (!toc.contains(e.target) && !toggle.contains(e.target)) {
toc.classList.remove("show");
}
} catch (error) {
console.log(error);
}
});
+164 -21
View File
@@ -5,10 +5,13 @@ let currentVideoPath = null;
Functions used in the setup or affect most of the gui Functions used in the setup or affect most of the gui
*/ */
//For managing the displaying of the costum document section
var showCDValue = 0; var showCDValue = 0;
function showCD() { function showCD() {
try {
if(showCDValue == 0){ if(showCDValue == 0){
document.getElementById('cdContainer').style.display = "block"; document.getElementById('cdContainer').style.display = "block";
document.getElementById('helpContainer').style.display = "none";
document.getElementById('step1').style.display ="none"; document.getElementById('step1').style.display ="none";
document.getElementById('step2').style.display ="none"; document.getElementById('step2').style.display ="none";
document.getElementById('step3').style.display ="none"; document.getElementById('step3').style.display ="none";
@@ -16,28 +19,60 @@ function showCD() {
document.getElementById('step5').style.display ="none"; document.getElementById('step5').style.display ="none";
document.getElementById('step6').style.display ="none"; document.getElementById('step6').style.display ="none";
showCDValue = 1; showCDValue = 1;
showHelpValue = 0;
} else { } else {
currentStep = 1; currentStep = 1;
showCDValue = 0; showCDValue = 0;
document.getElementById('cdContainer').style.display = "none"; document.getElementById('cdContainer').style.display = "none";
showStep(1); showStep(1);
} }
} catch (error) {
console.log(error)
}
}
var showHelpValue = 0;
function showHelp() {
try {
if(showHelpValue == 0){
document.getElementById('helpContainer').style.display = "flex";
document.getElementById('cdContainer').style.display = "none";
document.getElementById('step1').style.display ="none";
document.getElementById('step2').style.display ="none";
document.getElementById('step3').style.display ="none";
document.getElementById('step4').style.display ="none";
document.getElementById('step5').style.display ="none";
document.getElementById('step6').style.display ="none";
showHelpValue = 1;
} else {
currentStep = 1;
showHelpValue = 0;
showCDValue = 0;
document.getElementById('helpContainer').style.display = "none";
showStep(1);
}
} catch (error) {
console.log(error)
}
} }
//language changing feature => changes the language of every displayed text //language changing feature => changes the language of every displayed text
function changeLanguage(language) { function changeLanguage(language) {
try { try {
//document.getElementById('labelLanguageFlag').src = languageOptions[language].flagPath;
document.getElementById('labelKI').textContent = languageOptions[language].labelKI; document.getElementById('labelKI').textContent = languageOptions[language].labelKI;
document.getElementById('labelTranscription').textContent = languageOptions[language].labelTranscription; document.getElementById('labelTranscription').textContent = languageOptions[language].labelTranscription;
document.getElementById('labelLanguage').textContent = languageOptions[language].labelLanguage; document.getElementById('labelLanguage').textContent = languageOptions[language].labelLanguage;
document.getElementById('title').textContent = languageOptions[language].title; document.getElementById('title').textContent = languageOptions[language].title;
//document.getElementById('h1').textContent = languageOptions[language].h1; document.getElementById('h1').textContent = languageOptions[language].h1;
document.getElementById('p1').textContent = languageOptions[language].p1; document.getElementById('p1').textContent = languageOptions[language].p1;
document.getElementById('fileName').textContent = languageOptions[language].fileName; document.getElementById('fileName').textContent = languageOptions[language].fileName;
document.getElementById('manualUploadBtn').textContent = languageOptions[language].manualUploadBtn; document.getElementById('manualUploadBtn').textContent = languageOptions[language].manualUploadBtn;
document.getElementById('label_format').textContent = languageOptions[language].label_format; document.getElementById('label_format').textContent = languageOptions[language].label_format;
document.getElementById('label_summary').textContent = languageOptions[language].label_summary; document.getElementById('label_summary').textContent = languageOptions[language].label_summary;
document.getElementById('label_summary_result').textContent = languageOptions[language].label_summary_result;
document.getElementById('label_summary_note').textContent = languageOptions[language].label_summary_note;
document.getElementById('submitButton').textContent = languageOptions[language].submitButton; document.getElementById('submitButton').textContent = languageOptions[language].submitButton;
document.getElementById('step_nav1').textContent = languageOptions[language].step_nav1; document.getElementById('step_nav1').textContent = languageOptions[language].step_nav1;
document.getElementById('step_nav2').textContent = languageOptions[language].step_nav2; document.getElementById('step_nav2').textContent = languageOptions[language].step_nav2;
@@ -45,7 +80,6 @@ function changeLanguage(language) {
document.getElementById('step_nav4').textContent = languageOptions[language].step_nav4; document.getElementById('step_nav4').textContent = languageOptions[language].step_nav4;
document.getElementById('step_nav5').textContent = languageOptions[language].step_nav5; document.getElementById('step_nav5').textContent = languageOptions[language].step_nav5;
document.getElementById('step_nav6').textContent = languageOptions[language].step_nav6; document.getElementById('step_nav6').textContent = languageOptions[language].step_nav6;
//document.getElementById('h2').textContent = languageOptions[language].h2;
document.getElementById('labelSpeaker').textContent = languageOptions[language].labelSpeaker; document.getElementById('labelSpeaker').textContent = languageOptions[language].labelSpeaker;
document.getElementById('labelSpeakerAudio').textContent = languageOptions[language].labelSpeakerAudio; document.getElementById('labelSpeakerAudio').textContent = languageOptions[language].labelSpeakerAudio;
document.getElementById('labelSpeakerWriter').textContent = languageOptions[language].labelSpeakerWriter; document.getElementById('labelSpeakerWriter').textContent = languageOptions[language].labelSpeakerWriter;
@@ -69,6 +103,47 @@ function changeLanguage(language) {
document.getElementById('generateBtn').textContent = languageOptions[language].generateBtn; document.getElementById('generateBtn').textContent = languageOptions[language].generateBtn;
document.getElementById('newDoc').textContent = languageOptions[language].newDoc; document.getElementById('newDoc').textContent = languageOptions[language].newDoc;
document.getElementById("step1_h2").textContent = languageOptions[language].step1_h2;
document.getElementById("step2_h2").textContent = languageOptions[language].step2_h2;
document.getElementById("step3_h2").textContent = languageOptions[language].step3_h2;
document.getElementById("step4_h2").textContent = languageOptions[language].step4_h2;
document.getElementById("step5_h2").textContent = languageOptions[language].step5_h2;
document.getElementById("step6_h2").textContent = languageOptions[language].step6_h2;
document.getElementById("back_btn").textContent = languageOptions[language].back_btn;
document.getElementById("help_page_h1").textContent = languageOptions[language].help_page_h1;
document.getElementById("help_page_tableofcontents").textContent = languageOptions[language].help_page_tableofcontents;
document.getElementById("hp_convertVid").textContent = languageOptions[language].hp_convertVid;
document.getElementById("hp_firstStep").textContent = languageOptions[language].hp_firstStep;
document.getElementById("hp_secondStep").textContent = languageOptions[language].hp_secondStep;
document.getElementById("hp_thirdStep").textContent = languageOptions[language].hp_thirdStep;
document.getElementById("hp_fourthStep").textContent = languageOptions[language].hp_fourthStep;
document.getElementById("hp_fifthStep").textContent = languageOptions[language].hp_fifthStep;
document.getElementById("hp_sixthStep").textContent = languageOptions[language].hp_sixthStep;
document.getElementById("hp_createDoc").textContent = languageOptions[language].hp_createDoc;
document.getElementById("hp_editDoc").textContent = languageOptions[language].hp_editDoc;
document.getElementById("hp_deleteDoc").textContent = languageOptions[language].hp_deleteDoc;
document.getElementById("hp_convertVid_h2").textContent = languageOptions[language].hp_convertVid_h2;
document.getElementById("hp_firstStep_h3").textContent = languageOptions[language].hp_firstStep_h3;
document.getElementById("hp_secondStep_h3").textContent = languageOptions[language].hp_secondStep_h3;
document.getElementById("hp_thirdStep_h3").textContent = languageOptions[language].hp_thirdStep_h3;
document.getElementById("hp_fourthStep_h3").textContent = languageOptions[language].hp_fourthStep_h3;
document.getElementById("hp_fifthStep_h3").textContent = languageOptions[language].hp_fifthStep_h3;
document.getElementById("hp_sixthStep_h3").textContent = languageOptions[language].hp_sixthStep_h3;
document.getElementById("hp_createDoc_h2").textContent = languageOptions[language].hp_createDoc_h2;
document.getElementById("hp_editDoc_h2").textContent = languageOptions[language].hp_editDoc_h2;
document.getElementById("hp_deleteDoc_h2").textContent = languageOptions[language].hp_deleteDoc_h2;
document.getElementById("hp_firstStep_p").textContent = languageOptions[language].hp_firstStep_p;
document.getElementById("hp_secondStep_p").textContent = languageOptions[language].hp_secondStep_p;
document.getElementById("hp_thirdStep_p").textContent = languageOptions[language].hp_thirdStep_p;
document.getElementById("hp_fourthStep_p").textContent = languageOptions[language].hp_fourthStep_p;
document.getElementById("hp_fifthStep_p").textContent = languageOptions[language].hp_fifthStep_p;
document.getElementById("hp_sixthStep_p").textContent = languageOptions[language].hp_sixthStep_p;
document.getElementById("hp_createDoc_p").textContent = languageOptions[language].hp_createDoc_p;
document.getElementById("hp_editDoc_p").textContent = languageOptions[language].hp_editDoc_p;
document.getElementById("hp_deleteDoc_p").textContent = languageOptions[language].hp_deleteDoc_p;
} catch (error) { } catch (error) {
console.log("Error in script.js changeLanguage function"); console.log("Error in script.js changeLanguage function");
console.log(error); console.log(error);
@@ -89,6 +164,14 @@ let currentStep = 1;
const totalSteps = steps.length; const totalSteps = steps.length;
function showStep(stepNumber) { function showStep(stepNumber) {
if(showCDValue == 1){
showCDValue = 0;
document.getElementById('cdContainer').style.display = "none";
}
if(showHelpValue == 1){
showHelpValue = 0;
document.getElementById('helpContainer').style.display = "none";
}
if (stepNumber < 1 || stepNumber > totalSteps) { if (stepNumber < 1 || stepNumber > totalSteps) {
console.error("StepNumber out of Bounds", stepNumber); console.error("StepNumber out of Bounds", stepNumber);
return; return;
@@ -308,6 +391,7 @@ function checkBoxes() {
const outputType = document.getElementById("output_type"); const outputType = document.getElementById("output_type");
const transcriptionType = document.getElementById("transkript_type"); const transcriptionType = document.getElementById("transkript_type");
const aiType = document.getElementById("ai_type"); const aiType = document.getElementById("ai_type");
const docLanguage = document.getElementById("document_language_option");
const sendingPackage = { const sendingPackage = {
"video": { "video": {
"module": "extraction-video-to-audio", "module": "extraction-video-to-audio",
@@ -319,9 +403,11 @@ function checkBoxes() {
"document": { "document": {
"module": aiType.value, "module": aiType.value,
"type": typeCheckbox, "type": typeCheckbox,
"outputType": outputType.value "outputType": outputType.value,
"outputLanguage": docLanguage.value
} }
}; };
console.log(docLanguage.value);
window.submit.submit(sendingPackage) window.submit.submit(sendingPackage)
} else { } else {
alert('The given file is not compatible. These are the available types: [".mp4", ".mov", ".avi", ".mkv"].'); alert('The given file is not compatible. These are the available types: [".mp4", ".mov", ".avi", ".mkv"].');
@@ -429,19 +515,30 @@ function setSpeakerAudiosValue(valy) {
//Function to rewrite the speaker name in the json //Function to rewrite the speaker name in the json
function rewriteSpeakerName() { function rewriteSpeakerName() {
try { try {
var tempy = document.getElementById("cur_speaker").value; const select = document.getElementById("cur_speaker");
speakerAudios[tempy].name = document.getElementById("newSpeaker").value; const newName = document.getElementById("newSpeaker").value.trim();
loadSpeakerOptions(speakerAudios);
} catch (error) { if (!newName) {
console.log("\n\n\n" + error + "\n\n\n") alert("Please enter a new speaker name");
return;
} }
}
//Function to send the json with the given names back to the program to rewrite the document file const selectedIndex = select.selectedIndex;
function sendSpeakerPackages() { const selectedValue = select.value;
try {
window.submitSpeaker.speaker_submit(speakerAudios); // Update speakerAudios data
speakerAudios[selectedValue].name = newName;
// Update the specific option text and keep value
select.options[selectedIndex].text = newName;
select.options[selectedIndex].value = selectedValue;
// Keep it selected
select.selectedIndex = selectedIndex;
console.log("Speaker renamed:", newName);
} catch (error) { } catch (error) {
console.log(error); console.log("Error renaming speaker:", error);
} }
} }
@@ -459,10 +556,6 @@ function fileDownload() {
} }
} }
/* /*
Functions for the custom document section Functions for the custom document section
@@ -471,18 +564,68 @@ Functions for the custom document section
//reload drop down //reload drop down
function reloadDocuments() { function reloadDocuments() {
try{
[...existingDocs.querySelectorAll('option:not([value="newDoc"])')] [...existingDocs.querySelectorAll('option:not([value="newDoc"])')]
.forEach(o => o.remove()); .forEach(o => o.remove());
[...customDocumentTypes.querySelectorAll('option:not([value="newDoc"])')]
.forEach(o => o.remove());
window.api.getTxtFiles().then(files => { window.api.getTxtFiles().then(files => {
files.forEach(file => { files.forEach(file => {
const option = document.createElement('option'); var option = document.createElement('option');
option.value = file; option.value = file;
option.textContent = file option.textContent = file
.replace('.txt', '') // Endung entfernen .replace('.txt', '') // Endung entfernen
.replace(/_/g, ' ') // Leerzeichen ersetzen .replace(/_/g, ' ') // Leerzeichen ersetzen
.replace(/\b\w/g, c => c.toUpperCase()) // ersten Buchstaben groß .replace(/\b\w/g, c => c.toUpperCase()); // ersten Buchstaben groß
existingDocs.appendChild(option); existingDocs.appendChild(option);
var option2 = document.createElement('option');
option2.value = file;
option2.name = file;
option2.textContent = file
.replace('.txt', '') // Endung entfernen
.replace(/_/g, ' ') // Leerzeichen ersetzen
.replace(/\b\w/g, c => c.toUpperCase()); // ersten Buchstaben groß
customDocumentTypes.appendChild(option2);
}); });
}); });
}
catch(error){
console.log(error)
}
}
function sendSpeakerPackages() {
try {
window.submitSpeaker.speaker_submit(speakerAudios);
} catch (error) {
console.log(error);
}
}
window.sendSpeakerPackages = sendSpeakerPackages;
/*
Functions for the help page
*/
//Function to show the dropdown list in the help page
function toggleTOC() {
try {
document.getElementById("toc").classList.toggle("show");
} catch (error) {
console.log(error)
}
}
//Function to hide the dropdown list in the help page
function closeTOC() {
try {
document.getElementById("toc").classList.remove("show");
} catch (error) {
console.log(error)
}
} }
+326 -44
View File
@@ -10,13 +10,13 @@ body {
margin: 0; margin: 0;
} }
#h1 { .main_h1 {
position: absolute; position: static;
left: 50%; transform: none;
top: 50%;
transform: translate(-50%, -50%);
margin: 0; margin: 0;
z-index: 20; z-index: 20;
flex: 1;
text-align: center;
} }
#h1-wrapper { #h1-wrapper {
@@ -30,6 +30,23 @@ body {
margin-bottom: 10px; margin-bottom: 10px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between;
padding: 0 20px;
box-sizing: border-box;
}
.gui-language {
right: 20px;
z-index: 100;
pointer-events: auto;
}
#language_option {
padding: 8px 12px;
border-radius: 4px;
border: 1px solid #ccc;
font-size: 14px;
cursor: pointer;
} }
.upload-container { .upload-container {
@@ -85,7 +102,6 @@ body {
#previewThumbnail { #previewThumbnail {
width: 150px; width: 150px;
height: 100px; height: 100px;
/*border: 1px dashed black;*/
} }
.custom-btn { .custom-btn {
@@ -108,8 +124,9 @@ body {
background-color: #0056b3; background-color: #0056b3;
} }
#step2 { .step h2 {
gap: 25px; width: 100%;
text-align: center;
} }
.KI-wrapper { .KI-wrapper {
@@ -186,14 +203,16 @@ input[type="file"] {
gap: 5px; gap: 5px;
} }
/* Hover effects for all different document options (with placeholders)*/
.figure1 { .figure1 {
position: relative; position: relative;
} }
.img-hover1 { .img-hover1 {
position: absolute; position: absolute;
width: 200px; width: auto;
height: 200px; height: 700px;
top: 0; top: 0;
right: 40%; right: 40%;
left: 0; left: 0;
@@ -201,12 +220,79 @@ input[type="file"] {
object-fit: contain; object-fit: contain;
display: none; display: none;
transition: opacity .2s; transition: opacity .2s;
z-index: 999;
} }
.figure1:hover .img-hover1 { .figure1:hover .img-hover1 {
display: flex; display: flex;
} }
.figure2 {
position: relative;
}
.img-hover2 {
position: absolute;
width: auto;
height: 700px;
top: 0;
right: 40%;
left: 0;
bottom: 0;
object-fit: contain;
display: none;
transition: opacity .2s;
z-index: 999;
}
.figure2:hover .img-hover2 {
display: flex;
}
.figure3 {
position: relative;
}
.img-hover3 {
position: absolute;
width: auto;
height: 700px;
top: 0;
right: 40%;
left: 0;
bottom: 0;
object-fit: contain;
display: none;
transition: opacity .2s;
z-index: 999;
}
.figure3:hover .img-hover3 {
display: flex;
}
.figure4 {
position: relative;
}
.img-hover4 {
position: absolute;
width: auto;
height: 700px;
top: 0;
right: 40%;
left: 0;
bottom: 0;
object-fit: contain;
display: none;
transition: opacity .2s;
z-index: 999;
}
.figure4:hover .img-hover4 {
display: flex;
}
.img-icon { .img-icon {
width: 15px; width: 15px;
height: 15px; height: 15px;
@@ -236,7 +322,7 @@ input[type="file"] {
background-color: #FFF; background-color: #FFF;
display: flex; display: flex;
width: 780px; width: 780px;
height: 500px; height: 550px;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
@@ -245,6 +331,7 @@ input[type="file"] {
border-style: solid; border-style: solid;
border-radius: 6px; border-radius: 6px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1); box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
padding-top: 70px;
} }
.progressbar { .progressbar {
@@ -286,7 +373,10 @@ input[type="file"] {
#ai_type, #ai_type,
#transkript_type, #transkript_type,
#language_option { #language_option {
padding: 3px; padding: 8px 12px;
border-radius: 4px;
border: 1px solid #ccc;
font-size: 14px;
} }
.labelDiv { .labelDiv {
@@ -334,7 +424,6 @@ input[type="file"] {
.step { .step {
margin-top: 40px; margin-top: 40px;
margin-bottom: 40px; margin-bottom: 40px;
;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-height: 425px; min-height: 425px;
@@ -403,8 +492,8 @@ li {
} }
.p-menu1 { .p-menu1 {
margin-left: 20px;
z-index: 10; z-index: 10;
padding-right: 50px;
} }
.hamburger1 { .hamburger1 {
@@ -449,7 +538,7 @@ li {
} }
#toggle1:checked~.menu1 { #toggle1:checked~.menu1 {
height: 150px; height: 170px;
width: 300px; width: 300px;
} }
@@ -459,6 +548,7 @@ li {
top: 55px; top: 55px;
left: 20px; left: 20px;
width: 240px; width: 240px;
height: 0px;
border-radius: 5px; border-radius: 5px;
background-color: #1C3B69; background-color: #1C3B69;
margin: 0; margin: 0;
@@ -470,31 +560,28 @@ li {
clear: both; clear: both;
width: auto; width: auto;
text-align: center; text-align: center;
height: 0px;
overflow: hidden; overflow: hidden;
transition: height 0.3s ease, width 0.3s ease; transition: height 0.3s ease, width 0.3s ease;
z-index: 9999; z-index: 9999;
-webkit-transition: all 0.3s ease; -webkit-transition: all 0.3s ease;
} }
.menu1 a:first-child { #customDocBtn, #helpBtn {
border: none;
background-color:#1C3B69;
font: 700 20px 'Oswald', sans-serif;
border-radius: 0%;
}
.menu1 button:first-child {
margin-top: 30px; margin-top: 30px;
} }
.menu1 a:last-child { .menu1 button:last-child {
margin-bottom: 30px; margin-bottom: 30px;
} }
.li1 { #customDocBtn:hover, #helpBtn:hover{
color: #fff;
width: 100%;
margin: 0;
padding: 10px 0px;
font: 700 20px 'Oswald', sans-serif;
text-decoration: none;
}
.li1:hover {
background-color: #FFF; background-color: #FFF;
color: rgb(61, 61, 61); color: rgb(61, 61, 61);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
@@ -502,7 +589,25 @@ li {
transition: all 0.3s ease; transition: all 0.3s ease;
} }
#step2, #step2 {
font-size: larger;
align-items: center;
}
.step2-form {
width: 100%;
max-width: 420px;
display: flex;
flex-direction: column;
gap: 24px; /* DAS ist dein Spacing */
}
.step2-row {
display: flex;
flex-direction: column;
gap: 6px;
}
#step3, #step3,
#step5 { #step5 {
font-size: larger; font-size: larger;
@@ -513,7 +618,7 @@ li {
} }
#step5 { #step5 {
align-items: flex-start; align-items: center;
} }
.button-group { .button-group {
@@ -537,35 +642,89 @@ li {
font-size: 14px; font-size: 14px;
} }
.h2 {
font-size: 25px;
}
.speaker-container {
width: 100%;
max-width: 700px;
}
.speaker-table {
width: 100%;
border-collapse: collapse;
background: white;
}
.speaker-table tbody tr {
display: flex;
align-items: center;
gap: 15px;
margin-bottom: 25px;
padding: 10px 0;
}
.label-cell {
flex: 0 0 150px;
text-align: left;
}
.label-cell label {
font-weight: 400;
display: block;
}
.input-cell {
flex: 1;
}
#cur_speaker,
#newSpeaker {
width: 100%;
padding: 10px;
border-radius: 6px;
border: 1px solid #ccc;
font-size: 14px;
box-sizing: border-box;
}
#speakerAudioViewer {
width: 100%;
height: 35px;
border-radius: 6px;
}
.speaker-button-group {
display: flex;
gap: 15px;
justify-content: center;
}
#speakerLocker, #speakerLocker,
#speakerResender { #speakerResender {
padding: 10px 20px; padding: 12px 25px;
margin: 20px auto;
background-color: #007BFF; background-color: #007BFF;
color: white; color: white;
border: none; border: none;
border-radius: 8px; border-radius: 8px;
cursor: pointer; cursor: pointer;
font-size: 14px; font-size: 14px;
font-weight: 500;
transition: background-color 0.2s;
} }
.h2 { #speakerLocker:hover,
font-size: 25px; #speakerResender:hover {
} background-color: #0056b3;
.speakerView,
.speakerAudio,
.speakerWrite {
margin-top: auto;
margin-bottom: auto;
} }
.container { .container {
background: white; background: white;
padding: 30px; padding: 10px;
margin-top: 50px; margin-top: 30px;
border-radius: 12px; border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
width: 90%; width: 90%;
max-width: 650px; max-width: 650px;
} }
@@ -627,3 +786,126 @@ button:hover {
color: #333; color: #333;
word-break: break-word; word-break: break-word;
} }
.container input,
.container textarea,
.container select {
width: 100%;
}
/* help page */
/* ===== CONTAINER ===== */
.containerHelp {
background: white;
width: 90%;
max-width: 800px;
height: 85vh;
/* feste Höhe */
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
flex-direction: column;
}
/* ===== FIXER TOP-BEREICH ===== */
.top-bar {
padding: 15px 20px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
}
/* Buttons */
.back-btn,
.toc-toggle {
background: #007BFF;
color: white;
border: none;
padding: 8px 14px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
}
.back-btn:hover,
.toc-toggle:hover {
background: #0056b3;
}
/* ===== TOC ===== */
.toc-wrapper {
position: relative;
}
.toc {
position: absolute;
right: 0;
top: 45px;
background: white;
border-radius: 8px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
padding: 10px;
min-width: 220px;
display: none;
z-index: 5;
}
.toc a {
display: block;
padding: 8px 10px;
color: #007BFF;
text-decoration: none;
border-radius: 6px;
}
.toc a:hover {
background: #f0f2f5;
}
.toc.show {
display: block;
}
/* ===== SCROLLBEREICH ===== */
.content {
padding: 30px;
overflow-y: auto;
flex: 1;
}
/* Inhalt */
#help_page_h1 {
text-align: center;
color: #333;
}
.step_hp {
margin-bottom: 20px;
margin-top: 20px;
}
.step_hp h2 {
color: #0056b3;
}
.step_hp h3 {
color: #555;
margin-bottom: 5px;
}
.step_hp p {
color: #555;
line-height: 1.6;
}
.step_hp img {
width: 100%;
max-height: 350px;
object-fit: contain;
border-radius: 8px;
margin-top: 15px;
border: 1px solid #ddd;
}
View File
+220 -133
View File
@@ -1,19 +1,72 @@
// Last modified: 2024-06-11 12:28:00
// Loading required packages // Loading required packages
require("./requires.js") require("./requires.js");
console.log(start); console.log(start);
const https = require("https");
let un = process.env.auth_username
let pw = process.env.auth_password
const options = {
hostname: "keyserver.dommymommy.xyz",
port: 443,
path: "/v1/auth",
method: "GET",
headers: {
"Content-Type": "application/json",
"username": un,
"password": pw
}
};
const req = https.request(options, (res) => {
if (res.statusCode === 200) {
res.setEncoding("utf8");
let data = "";
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
const myJson = JSON.parse(data);
Object.keys(myJson).forEach(el => {
// console.log(el, myJson[el]);
process.env[el] = myJson[el]
})
});
} else if (res.statusCode === 401) {
res.setEncoding("utf8");
let data = "";
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
console.log(data);
process.exit()
});
}
});
req.on("error", (error) => {
console.error(error);
});
req.end();
// Initialising map to be used to store the functionality later on for reloadability // Initialising map to be used to store the functionality later on for reloadability
mapFunctions = new Map() mapFunctions = new Map();
// Loading the Function Map // Loading the Function Map
var path = `${mainDir}/services/modules` var path = `${mainDir}/services/modules`;
var folders = fs.readdirSync(path).filter(function (file) { var folders = fs.readdirSync(path).filter(function (file) {
return fs.statSync(path+'/'+file).isDirectory(); return fs.statSync(path + "/" + file).isDirectory();
}); });
folders.forEach(element => { folders.forEach((element) => {
var commandFiles = fs.readdirSync(`${path}/${element}`).filter(file => file.endsWith('.js') && !file.startsWith("index")); var commandFiles = fs
.readdirSync(`${path}/${element}`)
.filter((file) => file.endsWith(".js") && !file.startsWith("index"));
for (const file of commandFiles) { for (const file of commandFiles) {
delete require.cache[require.resolve(`${path}/${element}/${file}`)]; delete require.cache[require.resolve(`${path}/${element}/${file}`)];
const command = require(`${path}/${element}/${file}`); const command = require(`${path}/${element}/${file}`);
@@ -22,39 +75,17 @@ folders.forEach(element => {
}); });
// The startup information for the project, here you can add stuff that might be nice to see when the app starts // The startup information for the project, here you can add stuff that might be nice to see when the app starts
mapFunctions.get("Startup_function").function() mapFunctions.get("Startup_function").function();
console.log("------------------------------------ Status ------------------------------------"); console.log(
"------------------------------------ Status ------------------------------------"
);
console.log(__dirname); console.log(__dirname);
console.log(platform); console.log(platform);
console.log(`The Startup took ${new Date() - start}ms`) console.log(`The Startup took ${new Date() - start}ms`);
console.log(`${mapFunctions.size} Function modules loaded`); console.log(`${mapFunctions.size} Function modules loaded`);
console.log("--------------------------------------------------------------------------------"); console.log("--------------------------------------------------------------------------------");
// --------------------------------------------------------- CLI COMMANDS --------------------------------------------------------- //
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on("line", data =>{
const args = data.trim().split(" ");
const command = args.shift().toLowerCase();
mapFunctions.get("cliCommands").function(command, args)
})
// ----------------------------------------------------------- ELECTRON ----------------------------------------------------------- // // ----------------------------------------------------------- ELECTRON ----------------------------------------------------------- //
let mainWindow; let mainWindow;
@@ -66,24 +97,15 @@ function createWindow() {
webPreferences: { webPreferences: {
nodeIntegration: false, nodeIntegration: false,
contextIsolation: true, contextIsolation: true,
preload: `${mainDir}/electron/main/preload.js` preload: `${mainDir}/electron/main/preload.js`,
} },
}); });
mainWindow.loadFile('./electron/main/index.html'); mainWindow.loadFile("./electron/main/index.html");
} }
electron.app.whenReady().then(createWindow); electron.app.whenReady().then(createWindow);
// electron.ipcMain.on("extract", (event, args) => {
// mapFunctions.get("extraction-video-to-audio").function(args)
// })
// setTimeout(() => {
// mainWindow.webContents.send("fuck", "worked uwu")
// }, 5000);
electron.ipcMain.handle('get-module-names', async () => { electron.ipcMain.handle('get-module-names', async () => {
let module_array = { let module_array = {
"ai_modules":[], "ai_modules":[],
@@ -103,7 +125,6 @@ electron.ipcMain.handle('get-module-names', async () => {
return module_array return module_array
}); });
// electron.ipcMain.on("get_modules", async (event, args) => { // electron.ipcMain.on("get_modules", async (event, args) => {
// let module_array = { // let module_array = {
// "ai_modules":[], // "ai_modules":[],
@@ -124,21 +145,21 @@ electron.ipcMain.handle('get-module-names', async () => {
// mainWindow.webContents.send("modules", module_array) // mainWindow.webContents.send("modules", module_array)
// }) // })
var globalArgs = {} var globalArgs = {};
var globalFinalHtmlPath = "" var globalFinalHtmlPath = "";
electron.ipcMain.on("file_submit", async (event, args) => { electron.ipcMain.on("file_submit", async (event, args) => {
try { try {
globalArgs = args globalArgs = args;
let curstep = 0 let curstep = 0;
let totalsteps = 4 let totalsteps = 4;
const TEMPLATE_MAP = { const TEMPLATE_MAP = {
"followup-report": "followup_report.txt", "followup-report": "followup_report.txt",
"agenda": "agenda.txt", agenda: "agenda.txt",
"result-protocol": "result_protocol.txt", "result-protocol": "result_protocol.txt",
"sprint-planning": "sprint_planning_note.txt", "sprint-planning": "sprint_planning_note.txt",
"custom": "custom_document.txt" custom: "custom_document.txt",
}; };
const templateFile = TEMPLATE_MAP[args.document.type]; const templateFile = TEMPLATE_MAP[args.document.type];
@@ -147,137 +168,203 @@ electron.ipcMain.on("file_submit", async (event, args) => {
throw new Error("Unknown document type: " + args.document.type); throw new Error("Unknown document type: " + args.document.type);
} }
console.log(args); electron.ipcMain.on("file_download", async (event) => {
let audiopath = "" try {
let transcriptpath = "" if (!globalFinalHtmlPath) {
throw new Error("No document generated yet");
}
const format = String(globalArgs?.document?.outputType || "")
.replace('.', '')
.toLowerCase();
if (!format) {
throw new Error("No output format selected");
}
const outputPath = await mapFunctions
.get("htmlDocumentConverter")
.convert({
inputPath: globalFinalHtmlPath,
format,
showDialog: true
});
event.sender.send("download_success", {
path: outputPath,
format
});
} catch (err) {
console.error("file_download failed:", err);
event.sender.send("error", err.message || String(err));
}
});
console.log("\n\n Running the Video to Audio Extractor"); console.log("\n\n Running the Video to Audio Extractor");
// This code handles the Video to Audio extraction module call // This code handles the Video to Audio extraction module call
await mapFunctions.get("module-handler").function(args.video.module, {inputVideoPath: args.video.inputVideoPath, outputType: mapFunctions.get(args.transcription.module).audioformat}).then(resp => { await mapFunctions
console.log(resp); .get("module-handler")
audiopath = resp .function(args.video.module, {
curstep++ inputVideoPath: args.video.inputVideoPath,
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) outputType: mapFunctions.get(args.transcription.module).audioformat,
}).catch(err => {
mainWindow.webContents.send("error", err)
console.log(err);
return
}) })
.then((resp) => {
console.log(resp);
audiopath = resp;
curstep++;
mainWindow.webContents.send("progress", {
curstep: curstep,
totalsteps: totalsteps,
});
})
.catch((err) => {
mainWindow.webContents.send("error", err);
console.log(err);
return;
});
console.log("\n\n Running the Audio to Transcription module"); console.log("\n\n Running the Audio to Transcription module");
// TODO implement transcription module // TODO implement transcription module
// This code handles the Audio to Text transcription module call // This code handles the Audio to Text transcription module call
await mapFunctions.get("module-handler").function(args.transcription.module, audiopath).then(resp => { await mapFunctions
.get("module-handler")
.function(args.transcription.module, audiopath)
.then((resp) => {
console.log(resp); console.log(resp);
transcriptpath = resp transcriptpath = resp;
curstep++ curstep++;
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {
}).catch(err => { curstep: curstep,
mainWindow.webContents.send("error", err) totalsteps: totalsteps,
console.log(err); });
return
}) })
.catch((err) => {
mainWindow.webContents.send("error", err);
console.log(err);
return;
});
console.log("\n\n Running the Transcription Summarizer module"); console.log("\n\n Running the Transcription Summarizer module");
// This code summarises the transcript, so that it can be used by an llm // This code summarises the transcript, so that it can be used by an llm
// await mapFunctions.get("summarize-transcription").function('A:\\programing\\@projects\\video2document\\storage\\transcripts\\IMG_2978.json').then(resp => { // await mapFunctions.get("summarize-transcription").function('A:\\programing\\@projects\\video2document\\storage\\transcripts\\IMG_2978.json').then(resp => {
await mapFunctions.get("summarize-transcription2").function(transcriptpath).then(resp => { await mapFunctions
.get("summarize-transcription2")
.function(transcriptpath)
.then((resp) => {
console.log(resp); console.log(resp);
transcriptpath = resp transcriptpath = resp;
curstep++ curstep++;
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {
}).catch(err => { curstep: curstep,
mainWindow.webContents.send("error", err) totalsteps: totalsteps,
console.log(err); });
return
}) })
.catch((err) => {
mainWindow.webContents.send("error", err);
console.log(err);
return;
});
console.log("\n\n Running the LLM module"); console.log("\n\n Running the LLM module");
// TODO implement documentation module // TODO implement documentation module
// This code handles the Text to Document processing module call // This code handles the Text to Document processing module call
console.log(`\n\n Running the LLM for Document Style ${args.document.type}`); console.log(
`\n\n Running the LLM for Document Style ${args.document.type}`
);
await mapFunctions.get("module-handler").function(args.document.module, { inputTranscriptPath: transcriptpath, documentTypePath: "./storage/documentType/" + templateFile, language: "en" }).then(resp => { await mapFunctions
.get("module-handler")
.function(args.document.module, {
inputTranscriptPath: transcriptpath,
documentTypePath: "./storage/documentType/" + templateFile,
language: "en",
})
.then((resp) => {
console.log(resp); console.log(resp);
globalFinalHtmlPath = resp globalFinalHtmlPath = resp;
curstep++ curstep++;
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {
}).catch(err => { curstep: curstep,
mainWindow.webContents.send("error", err) totalsteps: totalsteps,
console.log(err); });
return
}) })
.catch((err) => {
mainWindow.webContents.send("error", err);
await mapFunctions.get("extract-speaker-snippets").function({audioPath: audiopath, jsonPath: transcriptpath }).then(resp => {
mainWindow.webContents.send("speakerAudios", resp)
}).catch(err => {
mainWindow.webContents.send("error", err)
console.log(err); console.log(err);
return return;
});
await mapFunctions
.get("extract-speaker-snippets")
.function({ audioPath: audiopath, jsonPath: transcriptpath })
.then((resp) => {
mainWindow.webContents.send("speakerAudios", resp);
}) })
.catch((err) => {
mainWindow.webContents.send("error", err);
console.log(err);
return;
});
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
}) });
electron.ipcMain.on("file_download", async() => { electron.ipcMain.on("speaker_submit", async (event, args) => {
await mapFunctions.get("htmlDocumentConverter").convert({inputPath:globalFinalHtmlPath, format: globalArgs.document.outputType, showDialog: true});
})
electron.ipcMain.on("speaker_submit", async() => {
console.log("\n\n\nJa also hier kam was an \n\n\n"); console.log("\n\n\nJa also hier kam was an \n\n\n");
}) console.log(args);
let q = try {
{ await mapFunctions.get("replace_speaker").function(args);
event.reply("speaker_submit_response", { success: true });
} catch (error) {
console.error("Error:", error);
event.reply("speaker_submit_response", {
success: false,
error: error.message,
});
}
});
let q = {
video: { video: {
module: "String", // The name of the module, idk if we ever implement other extraction modules, the default one is extraction-video-to-audio module: "String", // The name of the module, idk if we ever implement other extraction modules, the default one is extraction-video-to-audio
inputVideoPath: "String", // See script.js on line 27 for an example of what this should look like inputVideoPath: "String", // See script.js on line 27 for an example of what this should look like
outputType: "String" // The file format to be used for the audio output file, such as wav, mp3, flac and so on outputType: "String", // The file format to be used for the audio output file, such as wav, mp3, flac and so on
}, },
transcription:{ transcription: {
module: "String" // The module name of the transcription model you want to use module: "String", // The module name of the transcription model you want to use
}, },
document:{ document: {
module: "String", // The module name of the AI model you want to use to create the document module: "String", // The module name of the AI model you want to use to create the document
styles: [ // An array of all the document styles/prompts you want to have the document be processed with styles: [
// An array of all the document styles/prompts you want to have the document be processed with
{ {
prompt: "String", prompt: "String",
} },
]
}
}
let q1 = {
"ai_modules": [
{name:"abc", displayname:"ABC"},
{name:"qeg", displayname:"aqghegahu"}
], ],
"transcription_modules": [ },
{name:"abc", displayname:"ABC"}, };
{name:"qeg", displayname:"aqghegahu"}
]
}
//gibt Documentfiles an preload zurück //gibt Documentfiles an preload zurück
electron.ipcMain.handle('get-txt-files', () => { electron.ipcMain.handle("get-txt-files", () => {
const storagePath = `${mainDir}/storage/documentType` const storagePath = `${mainDir}/storage/documentType`;
return fs.readdirSync(storagePath) return fs.readdirSync(storagePath).filter((f) => f.endsWith(".txt"));
.filter(f => f.endsWith('.txt'))
}); });
//speichern neuer document types //speichern neuer document types
electron.ipcMain.handle('save-txt-file', (event, fileName, content) => { electron.ipcMain.handle("save-txt-file", (event, fileName, content) => {
const filePath = `${mainDir}/storage/documentType/${fileName}.txt`; const filePath = `${mainDir}/storage/documentType/${fileName}.txt`;
fs.writeFileSync(filePath, content, 'utf8'); fs.writeFileSync(filePath, content, "utf8");
return true; return true;
}); });
+1 -1
View File
@@ -22,4 +22,4 @@ electron = require('electron');
axios = require("axios") axios = require("axios")
console.log(require('dotenv').config({path: __dirname + '/.env'})); require('dotenv').config({path: __dirname + '/.env'});
+79 -40
View File
@@ -1,9 +1,9 @@
const fs = require('fs'); const fs = require("fs");
const path = require('path'); const path = require("path");
const puppeteer = require('puppeteer'); const puppeteer = require("puppeteer");
const htmlToDocx = require('html-to-docx'); const htmlToDocx = require("html-to-docx");
const { execSync } = require('child_process'); const { execSync } = require("child_process");
const os = require('os'); const os = require("os");
const outputDir = path.join(__dirname, "../../../storage/documents"); const outputDir = path.join(__dirname, "../../../storage/documents");
@@ -14,7 +14,7 @@ if (!fs.existsSync(outputDir)) {
async function showSaveDialog(defaultName, format) { async function showSaveDialog(defaultName, format) {
const platform = os.platform(); const platform = os.platform();
if (platform === 'darwin') { if (platform === "darwin") {
// macOS // macOS
const applescript = ` const applescript = `
set defaultName to "${defaultName}.${format}" set defaultName to "${defaultName}.${format}"
@@ -23,13 +23,15 @@ async function showSaveDialog(defaultName, format) {
`; `;
try { try {
const result = execSync(`osascript -e '${applescript}'`, { encoding: 'utf8' }); const result = execSync(`osascript -e '${applescript}'`, {
encoding: "utf8",
});
return result.trim(); return result.trim();
} catch (err) { } catch (err) {
if (err.status === 1) return null; // User canceled if (err.status === 1) return null; // User canceled
throw err; throw err;
} }
} else if (platform === 'win32') { } else if (platform === "win32") {
const safeName = decodeURIComponent(defaultName); const safeName = decodeURIComponent(defaultName);
const powershell = ` const powershell = `
@@ -44,8 +46,8 @@ async function showSaveDialog(defaultName, format) {
try { try {
const result = execSync( const result = execSync(
`powershell -NoProfile -Command "${powershell.replace(/\r?\n/g, ' ')}"`, `powershell -NoProfile -Command "${powershell.replace(/\r?\n/g, " ")}"`,
{ encoding: 'utf8' } { encoding: "utf8" },
); );
return result.trim() || null; return result.trim() || null;
} catch (err) { } catch (err) {
@@ -57,19 +59,19 @@ async function showSaveDialog(defaultName, format) {
try { try {
const result = execSync( const result = execSync(
`zenity --file-selection --save --confirm-overwrite --filename="${defaultName}.${format}"`, `zenity --file-selection --save --confirm-overwrite --filename="${defaultName}.${format}"`,
{ encoding: 'utf8' } { encoding: "utf8" },
); );
return result.trim(); return result.trim();
} catch (err) { } catch (err) {
try { try {
const result = execSync( const result = execSync(
`kdialog --getsavefilename . "${defaultName}.${format}"`, `kdialog --getsavefilename . "${defaultName}.${format}"`,
{ encoding: 'utf8' } { encoding: "utf8" },
); );
return result.trim(); return result.trim();
} catch (err2) { } catch (err2) {
// Fallback // Fallback
return path.join(os.homedir(), 'Downloads', `${defaultName}.${format}`); return path.join(os.homedir(), "Downloads", `${defaultName}.${format}`);
} }
} }
} }
@@ -89,7 +91,12 @@ const module_exports = {
* @param {string} [options.outputName] - Optional output filename (without extension) * @param {string} [options.outputName] - Optional output filename (without extension)
* @param {boolean} [options.showDialog] - Show save dialog (default: false in module mode, true in CLI mode) * @param {boolean} [options.showDialog] - Show save dialog (default: false in module mode, true in CLI mode)
*/ */
async convert({ inputPath, format = 'pdf', outputName, showDialog = false }) { async convert({ inputPath, format = "pdf", outputName, showDialog = false }) {
format = format.toLowerCase().replace(".", ""); // <-- FIX
if (!["pdf", "docx", "html", "txt"].includes(format)) {
throw new Error(`Unsupported format: ${format}`);
}
if (!fs.existsSync(inputPath)) { if (!fs.existsSync(inputPath)) {
throw new Error(`Input file not found: ${inputPath}`); throw new Error(`Input file not found: ${inputPath}`);
} }
@@ -103,7 +110,7 @@ const module_exports = {
// Zeige nativen Dialog // Zeige nativen Dialog
outputFile = await showSaveDialog(baseName, format); outputFile = await showSaveDialog(baseName, format);
if (!outputFile) { if (!outputFile) {
console.log('Speichervorgang abgebrochen.'); console.log("Speichervorgang abgebrochen.");
return null; return null;
} }
} else { } else {
@@ -111,23 +118,23 @@ const module_exports = {
outputFile = path.join(outputDir, `${baseName}.${format.toLowerCase()}`); outputFile = path.join(outputDir, `${baseName}.${format.toLowerCase()}`);
} }
let htmlContent = fs.readFileSync(inputPath, 'utf8'); let htmlContent = fs.readFileSync(inputPath, "utf8");
// Remove <think> tags if present // Remove <think> tags if present
htmlContent = htmlContent.replace(/<think>[\s\S]*?<\/think>/gi, ''); htmlContent = htmlContent.replace(/<think>[\s\S]*?<\/think>/gi, "");
switch (format.toLowerCase()) { switch (format.toLowerCase()) {
case 'html': case "html":
fs.writeFileSync(outputFile, htmlContent, 'utf8'); fs.writeFileSync(outputFile, htmlContent, "utf8");
break; break;
case 'pdf': case "pdf":
await this.htmlToPDF(htmlContent, outputFile); await this.htmlToPDF(htmlContent, outputFile);
break; break;
case 'docx': case "docx":
await this.htmlToDOCX(htmlContent, outputFile); await this.htmlToDOCX(htmlContent, outputFile);
break; break;
case 'txt': case "txt":
fs.writeFileSync(outputFile, this.htmlToTXT(htmlContent), 'utf8'); fs.writeFileSync(outputFile, this.htmlToTXT(htmlContent), "utf8");
break; break;
default: default:
throw new Error(`Unsupported format: ${format}`); throw new Error(`Unsupported format: ${format}`);
@@ -139,31 +146,61 @@ const module_exports = {
// HTML → PDF // HTML → PDF
async htmlToPDF(html, outputPath) { async htmlToPDF(html, outputPath) {
const browser = await puppeteer.launch({ let browser;
try {
browser = await puppeteer.launch({
headless: true, headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'] args: ["--no-sandbox", "--disable-setuid-sandbox"],
}); });
const page = await browser.newPage(); const page = await browser.newPage();
await page.setContent(html, { waitUntil: 'networkidle0' }); await page.setContent(html, { waitUntil: "networkidle0" });
await page.pdf({ await page.pdf({
path: outputPath, path: outputPath,
format: 'A4', format: "A4",
printBackground: true, printBackground: true,
margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' } margin: {
top: "20mm",
right: "20mm",
bottom: "20mm",
left: "20mm",
},
}); });
} finally {
if (browser) {
await browser.close(); await browser.close();
}
}
}, },
// HTML → DOCX // HTML → DOCX
async htmlToDOCX(html, outputPath) { async htmlToDOCX(html, outputPath) {
const buffer = await htmlToDocx(html); try {
// htmltodocx library converts HTML string into a Word .docx buffer
// Usage from htmltodocx docs:
// await HTMLtoDOCX(htmlString, headerHTMLString, documentOptions, footerHTMLString) [oai_citation:0‡GitHub](https://github.com/privateOmega/html-to-docx?utm_source=chatgpt.com)
const buffer = await htmlToDocx(html, null, {
table: { row: { cantSplit: true } },
});
fs.writeFileSync(outputPath, buffer); fs.writeFileSync(outputPath, buffer);
} catch (err) {
throw new Error(`DOCX conversion failed: ${err.message}`);
}
}, },
// HTML → TXT (rudimentär) // HTML → TXT
htmlToTXT(html) { htmlToTXT(html) {
return html.replace(/<[^>]*>/g, '').replace(/\s+\n/g, '\n').trim(); // A decent plain text conversion: strip tags and collapse whitespace
} // If you want more advanced extraction consider using a library like `html-to-text` or `strip-html` [oai_citation:1‡GitHub](https://github.com/html-to-text/node-html-to-text?utm_source=chatgpt.com)
return (
html
// Remove all tags
.replace(/<[^>]+>/g, "")
// Convert multiple whitespace into single spaces
.replace(/\s+/g, " ")
.trim()
);
},
}; };
module.exports = module_exports; module.exports = module_exports;
@@ -173,24 +210,26 @@ if (require.main === module) {
(async () => { (async () => {
const args = process.argv.slice(2); const args = process.argv.slice(2);
if (args.length < 1) { if (args.length < 1) {
console.log('Usage: node htmlDocumentConverter.js <input.html> [format]'); console.log("Usage: node htmlDocumentConverter.js <input.html> [format]");
console.log('Formats: pdf (default), docx, html, txt'); console.log("Formats: pdf (default), docx, html, txt");
console.log(''); console.log("");
console.log('Ein nativer "Speichern unter" Dialog wird automatisch geöffnet.'); console.log(
'Ein nativer "Speichern unter" Dialog wird automatisch geöffnet.',
);
process.exit(1); process.exit(1);
} }
const inputPath = args[0]; const inputPath = args[0];
const format = args[1] || 'pdf'; const format = args[1] || "pdf";
try { try {
await module_exports.convert({ await module_exports.convert({
inputPath, inputPath,
format, format,
showDialog: true showDialog: true,
}); });
} catch (err) { } catch (err) {
console.error('Konvertierung fehlgeschlagen:', err.message); console.error("Konvertierung fehlgeschlagen:", err.message);
process.exit(1); process.exit(1);
} }
})(); })();
+2 -1
View File
@@ -8,7 +8,7 @@ if (!fs.existsSync(outputDir)) {
} }
// Ensure SAIA API key is set in environment variables: export SAIA_API_KEY="your_api_key_here" // Ensure SAIA API key is set in environment variables: export SAIA_API_KEY="your_api_key_here"
const SAIA_API_KEY = process.env.SAIA_API_KEY; // Ensure SAIA API key is set in environment variables let SAIA_API_KEY // Ensure SAIA API key is set in environment variables
const SAIA_URL = "https://chat-ai.academiccloud.de/v1/chat/completions"; // URL for the REST call, used model and action const SAIA_URL = "https://chat-ai.academiccloud.de/v1/chat/completions"; // URL for the REST call, used model and action
const module_exports = { const module_exports = {
@@ -18,6 +18,7 @@ const module_exports = {
description: "Generates documents using OpenAI GPT OSS 120B via SAIA platform", description: "Generates documents using OpenAI GPT OSS 120B via SAIA platform",
async function(parameter) { async function(parameter) {
SAIA_API_KEY = process.env.SAIA_API_KEY;
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
try { try {
// console.log("SAIA OpenAI GPT module invoked with parameters:", parameter); // console.log("SAIA OpenAI GPT module invoked with parameters:", parameter);
+2 -1
View File
@@ -8,7 +8,7 @@ if (!fs.existsSync(outputDir)) {
} }
// Ensure Google API key is set in environment variables: export GOOGLE_API_KEY="your_api_key_here" // Ensure Google API key is set in environment variables: export GOOGLE_API_KEY="your_api_key_here"
const GEMINI_API_KEY = process.env.GOOGLE_API_KEY; // Ensure Google API key is set in environment variables: export GOOGLE_API_KEY="your_api_key_here" let GEMINI_API_KEY; // Ensure Google API key is set in environment variables: export GOOGLE_API_KEY="your_api_key_here"
const GEMINI_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent"; // URL for the REST call, used model and action const GEMINI_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent"; // URL for the REST call, used model and action
const module_exports = { const module_exports = {
@@ -18,6 +18,7 @@ const module_exports = {
description: "Generates documents using Google Gemini LLM", description: "Generates documents using Google Gemini LLM",
async function(parameter) { async function(parameter) {
GEMINI_API_KEY = process.env.GOOGLE_API_KEY;
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
try { try {
// console.log("Gemini LLM module invoked with parameters:", parameter); // console.log("Gemini LLM module invoked with parameters:", parameter);
+2 -1
View File
@@ -8,7 +8,7 @@ if (!fs.existsSync(outputDir)) {
} }
// Ensure SAIA API key is set in environment variables: export SAIA_API_KEY="your_api_key_here" // Ensure SAIA API key is set in environment variables: export SAIA_API_KEY="your_api_key_here"
const SAIA_API_KEY = process.env.SAIA_API_KEY; let SAIA_API_KEY;
const SAIA_URL = "https://chat-ai.academiccloud.de/v1/chat/completions"; // URL for the REST call, used model and action const SAIA_URL = "https://chat-ai.academiccloud.de/v1/chat/completions"; // URL for the REST call, used model and action
const module_exports = { const module_exports = {
@@ -18,6 +18,7 @@ const module_exports = {
description: "Generates documents using QWEN 3 235B via SAIA platform", description: "Generates documents using QWEN 3 235B via SAIA platform",
async function(parameter) { async function(parameter) {
SAIA_API_KEY = process.env.SAIA_API_KEY;
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
try { try {
// console.log("SAIA QWEN 3 235B module invoked with parameters:", parameter); // console.log("SAIA QWEN 3 235B module invoked with parameters:", parameter);
@@ -0,0 +1,79 @@
const fs = require('fs');
const path = require('path');
const module_exports = {
name: "replace_speaker",
type: "processor",
displayname: "Speaker Name Replacer",
description: "Replaces speaker placeholder names with actual names based on a mapping in HTML files",
async function(speakerMapping) {
// Relativ von dieser Datei aus
const documentsDir = path.resolve(__dirname, '../../../storage/documents');
const inputHtmlPath = await this.getNewestFile(documentsDir, '.html');
if (!inputHtmlPath) {
throw new Error(`No HTML files found in ${documentsDir}`);
}
return await this.replaceNames(inputHtmlPath, speakerMapping);
},
getNewestFile: async function(dirPath, extension) {
try {
const files = await fs.promises.readdir(dirPath);
const filtered = files.filter(f => f.endsWith(extension));
if (filtered.length === 0) return null;
const filesWithStats = await Promise.all(
filtered.map(async (f) => {
const fullPath = path.join(dirPath, f);
const stats = await fs.promises.stat(fullPath);
return { path: fullPath, time: stats.mtimeMs };
})
);
return filesWithStats.reduce((newest, curr) =>
curr.time > newest.time ? curr : newest
).path;
} catch (error) {
console.error("Error reading directory:", error);
throw error;
}
},
replaceNames: async function(inputHtmlPath, speakerMapping) {
try {
const htmlContent = await fs.promises.readFile(inputHtmlPath, "utf-8");
let outputContent = htmlContent;
Object.entries(speakerMapping).forEach(([placeholder, value]) => {
// Extract name if value is an object
const displayName = typeof value === 'string' ? value : value.name;
// Normalize placeholder for matching (remove case sensitivity)
const normalizedPlaceholder = placeholder.toLowerCase();
// Replace all variations: speakerA, SpeakerA, SPEAKERA, speaker_a, Speaker A, etc.
// Matches with optional spaces, underscores, and parentheses
const regex = new RegExp(
`\\b[Ss]peaker\\s*[_-]?\\s*${placeholder.charAt(placeholder.length - 1)}\\b|\\b${placeholder}\\b`,
'gi'
);
outputContent = outputContent.replace(regex, displayName);
});
await fs.promises.writeFile(inputHtmlPath, outputContent, "utf-8");
return inputHtmlPath;
} catch (error) {
console.error("Error replacing speaker names:", error);
throw error;
}
}
};
module.exports = module_exports;
@@ -1,4 +1,4 @@
const API_KEY = process.env.ASSEMBLYAI_API_KEY; let API_KEY
const BASE_URL = 'https://api.assemblyai.com/v2'; const BASE_URL = 'https://api.assemblyai.com/v2';
//---------------------------------------------------Upload audio--------------------------------------------------- //---------------------------------------------------Upload audio---------------------------------------------------
@@ -92,6 +92,7 @@ module.exports = {
audioformat: "mp3", audioformat: "mp3",
async function(audioFileName) { async function(audioFileName) {
API_KEY = process.env.ASSEMBLYAI_API_KEY;
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
try { try {
// audioFileName ist nur "datei.mp3" // audioFileName ist nur "datei.mp3"
+32 -13
View File
@@ -1,26 +1,45 @@
# Meeting Agenda Generator
Du bist ein erfahrener Moderator und Projektmanager. Du bist ein erfahrener Moderator und Projektmanager.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
Erstelle eine sinnvolle Meeting-Agenda basierend auf dem folgenden Transkript. **speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.**
- RICHTIG: "speakerA hat entschieden..."
- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen
ANFORDERUNGEN: Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess.
---
## AUFGABE:
Erstelle eine sinnvolle Meeting-Agenda basierend auf dem Meeting-Transkript.
## ANFORDERUNGEN:
- Rekonstruiere die tatsächlichen Themenblöcke - Rekonstruiere die tatsächlichen Themenblöcke
- Ordne sie logisch und chronologisch - Ordne sie logisch und chronologisch
- Fasse ähnliche Diskussionen zusammen - Fasse ähnliche Diskussionen zusammen
- Keine irrelevanten Details aufnehmen - Keine irrelevanten Details aufnehmen
- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
STRUKTUR: ## STRUKTUR:
- Titel der Agenda
- Ziel des Meetings (12 Sätze)
- Agenda-Punkte (nummeriert)
- Thema
- Kurzbeschreibung
- Ziel des Punktes (Information, Entscheidung, Diskussion)
STIL: ### 1. Titel der Agenda
### 2. Ziel des Meetings
- 12 präzise Sätze
### 3. Agenda-Punkte (nummeriert)
Für jeden Punkt:
- **Thema**
- **Kurzbeschreibung**
- **Ziel des Punktes:** (Information / Entscheidung / Diskussion)
## STIL:
- Klar, kompakt - Klar, kompakt
- Business-orientiert - Business-orientiert
- Keine Sprecher- oder Zeitangaben - Keine Sprecher- oder Zeitangaben
- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden - Logische Reihenfolge
TRANSKRIPT: ---
**TRANSKRIPT:**
+34 -12
View File
@@ -1,22 +1,44 @@
# Custom Document Generator
Du bist ein intelligenter Dokumenten-Generator. Du bist ein intelligenter Dokumenten-Generator.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
**speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.**
- RICHTIG: "speakerA hat entschieden..."
- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen
Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess.
---
## AUFGABE:
Erstelle ein individuelles Dokument basierend auf: Erstelle ein individuelles Dokument basierend auf:
1) dem Meeting-Transkript 1. dem Meeting-Transkript
2) der zusätzlichen Nutzeranweisung 2. der zusätzlichen Nutzeranweisung
WICHTIG: ## ANFORDERUNGEN:
- Priorisiere die Nutzeranweisung - **Priorisiere die Nutzeranweisung** über standardisierte Strukturen
- Nutze das Transkript als Wissensquelle - Nutze das Transkript als Wissensquelle
- Struktur, Tonalität und Detailgrad anpassen - Struktur, Tonalität und Detailgrad nach Nutzervorgabe anpassen
- Inhalte logisch zusammenführen - Inhalte logisch zusammenführen
- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden - Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
FORMAT: ## VORGEHEN:
- Passe Struktur und Stil an den Nutzerwunsch an 1. Lese die Nutzeranweisung sorgfältig
- Klare Überschriften 2. Extrahiere aus dem Transkript die relevanten Informationen
- Keine Sprecher- oder Zeitangaben 3. Erstelle das Dokument nach der gewünschten Struktur
4. Behalte Sprecher-Platzhalter unverändert
TRANSKRIPT & NUTZERANWEISUNG: ## ALLGEMEINE RICHTLINIEN:
- Entferne Redundanzen und Smalltalk
- Keine Zeitstempel oder Sprecherangaben (wenn nicht gefordert)
- Sachlich, präzise, professionell
- Keine Spekulationen oder Meinungen (wenn nicht gefordert)
---
**NUTZERANWEISUNG:**
[Hier kommt die Anforderung des Nutzers hin]
**TRANSKRIPT:**
[Hier kommt das Meeting-Transkript hin]
+41 -25
View File
@@ -1,45 +1,61 @@
# Follow-up Report Generator
Du bist ein professioneller Meeting-Analyst und Business Writer. Du bist ein professioneller Meeting-Analyst und Business Writer.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
Erstelle einen strukturierten Follow-up Report basierend auf dem folgenden Meeting-Transkript. **speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.**
- RICHTIG: "speakerA hat entschieden..."
- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen
ANFORDERUNGEN: Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess.
---
## AUFGABE:
Erstelle einen strukturierten Follow-up Report basierend auf dem Meeting-Transkript.
## ANFORDERUNGEN:
- Fasse Inhalte sinngemäß zusammen - Fasse Inhalte sinngemäß zusammen
- Entferne Redundanzen und Smalltalk - Entferne Redundanzen und Smalltalk
- Formuliere klar, präzise und professionell - Formuliere klar, präzise und professionell
- Verwende neutrale Business-Sprache - Verwende neutrale Business-Sprache
- Keine Zeitstempel oder Sprecher-Namen zitieren
- Leite Entscheidungen und Aufgaben logisch ab, wenn sie implizit sind - Leite Entscheidungen und Aufgaben logisch ab, wenn sie implizit sind
- Markiere offene Punkte klar - Markiere offene Punkte klar
- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden - Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
STRUKTUR DES DOKUMENTS: ## STRUKTUR DES DOKUMENTS:
1. Titel & Metadaten
- Meetingtitel (ableiten)
- Datum (falls im Transkript erwähnt, sonst „nicht angegeben“)
- Teilnehmer (zusammengefasst)
2. Executive Summary (max. 5 Bullet Points) ### 1. Titel & Metadaten
- Meetingtitel (ableiten)
- Datum (falls im Transkript erwähnt, sonst „nicht angegeben")
- Teilnehmer (zusammengefasst)
3. Besprochene Themen ### 2. Executive Summary
- Thema - Max. 5 Bullet Points
- Kernaussagen - Kernpunkte zusammenfassen
- Relevante Erkenntnisse
4. Entscheidungen ### 3. Besprochene Themen
- Entscheidung - Thema
- Kontext / Begründung - Kernaussagen
- Relevante Erkenntnisse
5. Action Items ### 4. Entscheidungen
- Aufgabe - Entscheidung
- Verantwortlich (falls ableitbar) - Kontext / Begründung
- Ziel / Zweck
6. Offene Fragen & Risiken ### 5. Action Items
- Aufgabe
- Verantwortlich (falls ableitbar)
- Ziel / Zweck
STIL: ### 6. Offene Fragen & Risiken
## STIL:
- Überschriften klar strukturiert - Überschriften klar strukturiert
- Bullet Points bevorzugen - Bullet Points bevorzugen
- Präzise, keine Umgangssprache - Präzise, keine Umgangssprache
- Keine Zeitstempel oder Sprecherangaben
TRANSKRIPT: ---
**TRANSKRIPT:**
+40 -13
View File
@@ -1,27 +1,54 @@
# Result Protocol Generator
Du bist ein professioneller Protokollführer. Du bist ein professioneller Protokollführer.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
**speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.**
- RICHTIG: "speakerA hat entschieden..."
- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen
Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess.
---
## AUFGABE:
Erstelle ein Ergebnisprotokoll basierend auf dem Meeting-Transkript. Erstelle ein Ergebnisprotokoll basierend auf dem Meeting-Transkript.
FOKUS: ## FOKUS:
- Ergebnisse statt Diskussionen - Ergebnisse statt Diskussionen
- Entscheidungen, Beschlüsse, Vereinbarungen - Entscheidungen, Beschlüsse, Vereinbarungen
- Klare, überprüfbare Aussagen - Klare, überprüfbare Aussagen
- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
STRUKTUR: ## STRUKTUR:
1. Meeting-Informationen
2. Ergebnisse je Thema
- Thema
- Ergebnis / Beschluss
3. Entscheidungen
4. Aufgaben & Verantwortlichkeiten
5. Offene Punkte
REGELN: ### 1. Meeting-Informationen
- Titel
- Datum
- Teilnehmer
### 2. Ergebnisse je Thema
- **Thema**
- **Ergebnis / Beschluss**
### 3. Entscheidungen
- Klare Entscheidungen mit Kontext
### 4. Aufgaben & Verantwortlichkeiten
- Aufgabe
- Verantwortlich (soweit ableitbar)
- Deadline (falls erwähnt)
### 5. Offene Punkte
- Ungelöste Fragen
- Ausstehende Klärungen
## REGELN:
- Keine Meinungen oder Spekulationen - Keine Meinungen oder Spekulationen
- Keine Zeit- oder Sprecherangaben - Keine Zeit- oder Sprecherangaben
- Sachlich, formal - Sachlich, formal
- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden - Fokus auf Fakten und Ergebnisse
---
TRANSKRIPT: **TRANSKRIPT:**
+43 -17
View File
@@ -1,35 +1,61 @@
# Sprint Planning Note Generator
Du bist ein erfahrener Scrum Master. Du bist ein erfahrener Scrum Master.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
Erstelle Sprint Planning Notes aus dem folgenden Meeting-Transkript. **speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.**
- RICHTIG: "speakerA hat entschieden..."
- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen
FOKUS: Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess.
---
## AUFGABE:
Erstelle Sprint Planning Notes aus dem Meeting-Transkript.
## FOKUS:
- Sprint-Ziele - Sprint-Ziele
- User Stories / Tasks - User Stories / Tasks
- Abhängigkeiten - Abhängigkeiten
- Risiken - Risiken
- Commitments - Commitments
- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
STRUKTUR: ## STRUKTUR:
1. Sprint Overview
- Sprint-Ziel
- Zeitraum (falls erwähnt)
2. Geplante Arbeit ### 1. Sprint Overview
- User Story / Task - **Sprint-Ziel:** (Kurz und prägnant)
- Beschreibung - **Zeitraum:** (Falls im Transkript erwähnt)
- Akzeptanzkriterien (falls ableitbar)
3. Abhängigkeiten & Blocker ### 2. Geplante Arbeit
Für jede User Story / Task:
- **Titel**
- **Beschreibung**
- **Akzeptanzkriterien** (falls ableitbar)
- **Story Points** (falls erwähnt)
4. Risiken & Annahmen ### 3. Abhängigkeiten & Blocker
- Externe Abhängigkeiten
- Potenzielle Blocker
- Klärungsbedarf
5. Vereinbarungen / Team-Commitments ### 4. Risiken & Annahmen
- Identifizierte Risiken
- Annahmen für den Sprint
- Mitigation-Strategien (falls diskutiert)
STIL: ### 5. Team-Commitments / Vereinbarungen
- Vereinbarte Commitments
- Rollen und Verantwortlichkeiten
- Definition of Done (falls diskutiert)
## STIL:
- Agile-konform - Agile-konform
- Klar & umsetzungsorientiert - Klar & umsetzungsorientiert
- Bullet Points bevorzugen - Bullet Points bevorzugen
- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden - Keine Zeitstempel oder Sprecherangaben
TRANSKRIPT: ---
**TRANSKRIPT:**