<!-- .slide: data-background="linear-gradient(to bottom right, #2b5876, #4e4376)" --> # F0rmF0551l ## When Retro Meets Reality 🦕 <br> A journey through time with ("outdated") form processing Note: Open in Vivaldi --- ## Was ist F0rmF0551l? 🤔 <br> - F0rmF0551l = **FormFossil** - Ein Formular-Verarbeitungssystem geschrieben in Rust - Bringt den Charme alter Internet-Protokolle in die moderne Welt - Unterstützt multiple Interfaces für maximalen Retro-Spaß - Perfekt für Vereine, Hackspaces und alle, die Formulare hassen 😉 Note: - Es ist einfach ein Fun-Projekt - mit Hoffnung auf Spaceeinsatz - Entstanden aus der Idee, Formulare weniger langweilig zu machen - es geht spezifisch eher um Anträge als um grundsätzliche Formulare, aber Application Fossil klingt halt sch**** - Gleichzeitig ein Experiment in Rust, der Protokoll-Implementierung und der Digitalisierung von verstaubten Formularen - Perfekt für alle die Formulare hassen .. sie werden sie danach nur noch mehr hassen --- ## Die Tech-Stack Highlights 🚀 <br> - 🦀 **Rust Backend** - Modulare Protocol und Submission Handler Implementierung - Asynchrone Annahme und Verarbeitung mit Tokio - 🔒 **Type-safe Formulardefinitionen** in JSON Schema - 📝 **PDF-Template System**: Custom Template Engine auf Basis von lopdf - 📡 **Native Implementierung der User Interfaces** - **Telnet** (für echte Terminal-Fans; inkl. 🎨 ANSI-Art) - **Gopher** (90er Internet FTW!) - Web (für Normalos) Note: - Rust Backend gewählt für Performance, Type-Safety und Lerneffekt - Modulare Protocol und Submission Handler Implementierung - Asynchrone Annahme und Verarbeitung mit Tokio - Native Rust Implementierung für die verwendeten User Interface Protokolle - keine externen Server - keine telnet oder gopher lib - web mit axum und handlebars - PDF-System basiert auf low-level PDF Manipulation mit lopdf - Nicht perfekt, aber funktional - nice to know: Telnet Interface unterstützt ANSI Farben - Gopher implementiert die wichtigsten Teile des Protokolls für Formulare - dazu nachher noch etwas mehr --- ## Technischer Deep-Dive: Architektur 🛠 ### Modulare Architektur <br> - Anträge / Formulare werden als .json einfach in einen Ordner gelegt - unabhängige, async, protokollspezische **User Interface Handler** - protokollspezisches Rendering der Formulare - Gemeinsame **Core Logic für Validierung** - voneinander unabhängige **SubmissionStrategy** Implementierungen - **Submission Queue** zur Abarbeitung der Submission Strategies Note: - Die json Antragsdateien werden beim Applikations(neu)start eingelesen - Es gibt technische Herausforderungen, weshalb ein App interner Reload schwierig, aber nicht unmöglich ist. Wäre eine Idee für die Zukunft. Oder einfach nur Overengineering. - Jedes implementierte Protokoll bzw. User Interface hat einen eigenen Renderer für die Anträge - Gemeinsame Core Logic für die Validierung der Formularfelder - Submission Queue für asynchrone Verarbeitung von übermittelten Formularen - Die SubmissionStrategy Implementierungen haben alle das gleiche Interface für die Annahme von zu verarbeitenden Anträgen, die dann über die Submission Queue entsprechend aufgerufen werden ---- ## Technischer Deep-Dive: Architektur 🛠 ### Submission <br> ```rust // Initialize submission strategies let mut strategies: Vec<Box<dyn SubmissionStrategy + Send + Sync>> = Vec::new(); // Add email strategy if enabled if let Some(email_config) = &config.submission.email { if email_config.enabled { strategies.push(Box::new(EmailSubmissionStrategy::new( EmailSubmissionConfig { ... // Add cleanup strategy last - it will run after all other strategies strategies.push(Box::new(CleanupStrategy::new(file_upload_manager.clone()))); // Create shared submission strategies and queue let submission_strategies = Arc::new(strategies); let submission_queue = SubmissionQueue::new(submission_strategies.clone()); ``` ---- ## Technischer Deep-Dive: Architektur 🛠 ### Submission Queue <br> ```rust impl SubmissionQueue { pub fn new(strategies: Arc<Vec<Box<dyn SubmissionStrategy + Send + Sync>>>) -> Self { let (sender, mut receiver) = mpsc::channel(42); // Buffer size of 42 submissions // Spawn background worker tokio::spawn(async move { while let Some(submission) = receiver.recv().await { // Process submission with all strategies for strategy in strategies.iter() { if let Err(e) = strategy.submit(&submission).await { eprintln!("Error processing submission: {}", e); } } } }); Self { sender } } pub async fn submit( &self, submission: ApplicationSubmission, ) -> Result<(), Box<dyn Error + Send + Sync>> { self.sender.send(submission).await.map_err(|e| { Box::new(InterfaceError::Processing(format!( "Failed to queue submission: {}", e ))) as Box<dyn Error + Send + Sync> }) } } ``` ---- ## Technischer Deep-Dive: Architektur 🛠 ### User interfaces <br> ```rust // Protocol Handler Interfaces let telnet_interface = TelnetInterface::new( config.server.telnet_address.parse()?, applications.clone(), submission_queue.clone(), file_upload_manager.clone(), config.server.show_demo_notice, ); // Run all interfaces concurrently tokio::select! { result = web_interface.start() => { if let Err(e) = result { eprintln!("Web interface error: {}", e); } } result = telnet_interface.start() => { if let Err(e) = result { eprintln!("Telnet interface error: {}", e); } } result = gopher_interface.start() => { if let Err(e) = result { eprintln!("Gopher interface error: {}", e); } } result = file_upload_server.start() => { if let Err(e) = result { eprintln!("File upload server error: {}", e); } } _ = shutdown_signal() => { println!("\nShutting down..."); } } ``` --- ## Deployment Optionen 🐳 1. **Docker** (für die Container-Fans): ```bash # Latest Stable (mit example config; deaktivierter Email Versand) docker run -d \ --name f0rmf0551l \ -p 3000:3000 \ -p 3023:3023 \ -p 7070:7070 \ -p 7071:7071 \ docker.maglab.space/binsky/f0rmf0551l:latest ``` 2. **Bare Metal** (für Puristen): ```bash # Build from source git clone https://git.maglab.space/binsky/f0rmf0551l cd f0rmf0551l cargo build --release # Run with custom config ./target/release/f0rmf0551l -c config.toml ``` Note: - Docker Images sind ca ~100MB groß - Volumes für einfache Konfiguration (mehr Details in der Projekt README) --- ## Coole Hacks & Features 🛠 <small style="color: chartreuse; margin-top: 2rem; margin-left: 2rem;">(ja, noch mehr!)</small> <br> - **PDF Magie**: - Windows-1252 Encoding für PDF Kompatibilität - Fake Checkboxes in PDFs via Text-Fields - **Protocol Tricks**: - "a bissl" ASCII Art im Telnet Interface - ANSI Escape Sequences <span style="background-image: radial-gradient(circle at bottom, #ff0000, #4b00ff); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">für Farben</span> im Telnet UI - Gopher Menu Rendering - ![](https://pad.binsky.org/uploads/fb913b46-dd95-48bf-8367-b6619d701e14.png =600x) Note: - wilde PDF Hacks waren notwendig für Kompatibilität zu Radio-Buttons / Checkboxen - "a bissl" ASCII Art im Telnet Interface - Telnet unterstützt ANSI Farben - Gopher Menüs sind quasi über Ordner gelöst, und der State dauerhaft in der URL/Query gehalten und aktualisiert - soll heißen man ruft eigentlich mega viele verschiedene dynamisch generierte API Endpunkt auf, um Eingaben zu verarbeiten und eine Art Menüführung zu haben --- ## Live Demo Time! 💻 <br> ```bash # Via Telnet (Raw Terminal Experience) telnet f0rmf0551l.binsky.dev 3023 # Via Gopher (90s Style) sacc gopher://f0rmf0551l.binsky.dev:7070 # Oder Web (langweilig...) http://f0rmf0551l.binsky.dev ``` Note: - Browser links anordnen: Meta + <- - Terminal in der FormFossil Dev nix-shell nach rechts - Live Demo: Zeige gleiches Formular in allen drei Interfaces - Demonstriere ANSI-Farben im Telnet - Zeige Gopher in Lynx und modernem Browser (wenn möglich) --- ## Mitmachen & Beitragen 🤝 <br> - Links und Infos: [wiki.maglab.space](https://wiki.maglab.space/de/Projekte/F0rmF0551l) -> Projekte -> F0rmF0551l - Ideen für neue Retro-Protokolle? - FidoNet Support? - BBS Integration? - IRC Bot Interface? - Serial Port Support? - (Issues) und PRs sehr willkommen! Note: - Perfektes Projekt zum Rust lernen - Viele interessante Protocol-Details - Community-Driven Development --- ## Danke! 👾 <br> Keep the retro spirit alive! <br> 🕹️ 📟 💾 🖥️ --- ## Q&A 🎤 Fragen? Ideen? Retro-Computing Stories? Note: - Hier ist Zeit für Diskussion und Erfahrungsaustausch - Live Demo von speziellen Features auf Anfrage - Zeige gerne auch den Source Code
{"title":"F0rmF0551l - When Retro Meets Reality","tags":"presentation, rust, retro-computing","type":"slide","slideOptions":{"transition":"slide","theme":"black","width":"80%"}}