diff options
| author | Paul Buetow <paul@buetow.org> | 2025-07-12 11:19:35 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-07-12 11:19:35 +0300 |
| commit | 546a287aaab3d27133a2e81ccb94b228d2b3e42c (patch) | |
| tree | 0a6cadf73f0c6214239fa4a13b0527ec53657c98 /about | |
| parent | 7ae9bcb0a709862f2c068a2b86468b5e433afd8a (diff) | |
more about this
Diffstat (limited to 'about')
| -rw-r--r-- | about/showcase.gmi.tpl | 1127 | ||||
| -rw-r--r-- | about/showcase/debroid/image-1.png | 124 |
2 files changed, 615 insertions, 636 deletions
diff --git a/about/showcase.gmi.tpl b/about/showcase.gmi.tpl index 15891610..7e1bb251 100644 --- a/about/showcase.gmi.tpl +++ b/about/showcase.gmi.tpl @@ -1,6 +1,6 @@ # Project Showcase -Generated on: 2025-07-09 +Generated on: 2025-07-12 This page showcases my side projects, providing an overview of what each project does, its technical implementation, and key metrics. Each project summary includes information about the programming languages used, development activity, and licensing. The projects are ordered by recent activity, with the most actively maintained projects listed first. @@ -9,13 +9,13 @@ This page showcases my side projects, providing an overview of what each project ## Overall Statistics * ๐ฆ Total Projects: 55 -* ๐ Total Commits: 10,405 -* ๐ Total Lines of Code: 231,007 -* ๐ Total Lines of Documentation: 24,381 -* ๐ป Languages: Java (23.7%), Go (19.2%), C++ (16.1%), C/C++ (8.9%), C (8.3%), Perl (7.3%), Shell (6.4%), Config (2.0%), HTML (2.0%), Ruby (1.2%), HCL (1.2%), Make (0.8%), Python (0.7%), CSS (0.6%), Raku (0.4%), JSON (0.3%), XML (0.3%), Haskell (0.3%), YAML (0.2%), TOML (0.1%) -* ๐ Documentation: Text (46.3%), Markdown (39.6%), LaTeX (14.1%) -* ๐ค AI-Assisted Projects: 6 out of 55 (10.9% AI-assisted, 89.1% human-only) -* ๐ Release Status: 31 released, 24 experimental (56.4% with releases, 43.6% experimental) +* ๐ Total Commits: 10,425 +* ๐ Total Lines of Code: 156,358 +* ๐ Total Lines of Documentation: 21,300 +* ๐ป Languages: Go (30.3%), Java (25.9%), Perl (9.9%), C (9.0%), C/C++ (5.1%), Shell (4.1%), C++ (3.3%), HTML (1.9%), Config (1.9%), Ruby (1.8%), HCL (1.8%), Python (1.0%), Make (0.9%), Raku (0.8%), JSON (0.5%), CSS (0.5%), XML (0.4%), Haskell (0.4%), YAML (0.3%), TOML (0.2%) +* ๐ Documentation: Text (51.2%), Markdown (46.1%), LaTeX (2.7%) +* ๐ค AI-Assisted Projects: 8 out of 55 (14.5% AI-assisted, 85.5% human-only) +* ๐ Release Status: 32 released, 23 experimental (58.2% with releases, 41.8% experimental) ## Projects @@ -27,7 +27,7 @@ This page showcases my side projects, providing an overview of what each project * ๐ Lines of Code: 6548 * ๐ Lines of Documentation: 2338 * ๐
Development Period: 2025-06-23 to 2025-07-09 -* ๐ฅ Recent Activity: 3.4 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 6.1 days (avg. age of last 42 commits) * โ๏ธ License: BSD-2-Clause * ๐ท๏ธ Latest Release: v0.5.0 (2025-07-09) * ๐ค AI-Assisted: This project was partially created with the help of generative AI @@ -40,19 +40,23 @@ The tool is implemented in Go with a clean architecture that supports both indiv => https://codeberg.org/snonux/gitsyncer View on Codeberg => https://github.com/snonux/gitsyncer View on GitHub -Go from `internal/cli/handlers.go`: +Go from `internal/sync/branch_filter.go`: ```AUTO -func LoadConfig(configPath string) (*config.Config, error) { - if configPath == "" { - configPath = findDefaultConfigPath() - if configPath == "" { - return nil, fmt.Errorf("no configuration file found") +func NewBranchFilter(excludePatterns []string) (*BranchFilter, error) { + filter := &BranchFilter{ + excludePatterns: make([]*regexp.Regexp, 0, len(excludePatterns)), + } + + for _, pattern := range excludePatterns { + re, err := regexp.Compile(pattern) + if err != nil { + return nil, fmt.Errorf("invalid regex pattern '%s': %w", pattern, err) } + filter.excludePatterns = append(filter.excludePatterns, re) } - - fmt.Printf("Loaded configuration from: %s\n", configPath) - return config.Load(configPath) + + return filter, nil } ``` @@ -66,7 +70,7 @@ func LoadConfig(configPath string) (*config.Config, error) { * ๐ Lines of Code: 873 * ๐ Lines of Documentation: 135 * ๐
Development Period: 2025-06-25 to 2025-06-29 -* ๐ฅ Recent Activity: 12.9 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 15.6 days (avg. age of last 42 commits) * โ๏ธ License: BSD-2-Clause * ๐งช Status: Experimental (no releases yet) * ๐ค AI-Assisted: This project was partially created with the help of generative AI @@ -79,10 +83,14 @@ The project is implemented using a clean modular architecture with the CLI entry => https://codeberg.org/snonux/timr View on Codeberg => https://github.com/snonux/timr View on GitHub -Go from `internal/version.go`: +Go from `internal/live/live.go`: ```AUTO -const Version = "v0.0.0" +func tick() tea.Cmd { + return tea.Tick(time.Second, func(t time.Time) tea.Msg { + return tickMsg(t) + }) +} ``` --- @@ -95,7 +103,7 @@ const Version = "v0.0.0" * ๐ Lines of Code: 6160 * ๐ Lines of Documentation: 162 * ๐
Development Period: 2025-06-19 to 2025-07-08 -* ๐ฅ Recent Activity: 13.3 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 16.0 days (avg. age of last 42 commits) * โ๏ธ License: BSD-2-Clause * ๐ท๏ธ Latest Release: v0.9.2 (2025-07-02) * ๐ค AI-Assisted: This project was partially created with the help of generative AI @@ -112,38 +120,27 @@ The implementation follows a clean architecture with clear separation of concern => https://codeberg.org/snonux/tasksamurai View on Codeberg => https://github.com/snonux/tasksamurai View on GitHub -Go from `internal/ui/table.go`: +Go from `internal/task/task.go`: ```AUTO -func editDescriptionCmd(description string) tea.Cmd { - return func() tea.Msg { - tmpFile, err := os.CreateTemp("", "tasksamurai-desc-*.txt") - if err != nil { - return descEditDoneMsg{err: err, tempFile: ""} - } - tmpPath := tmpFile.Name() - - _, err = tmpFile.WriteString(description) - tmpFile.Close() - if err != nil { - os.Remove(tmpPath) - return descEditDoneMsg{err: err, tempFile: ""} - } - - editor := os.Getenv("EDITOR") - if editor == "" { - editor = "vi" - } - - c := exec.Command(editor, tmpPath) - c.Stdin = os.Stdin - c.Stdout = os.Stdout - c.Stderr = os.Stderr - - return tea.ExecProcess(c, func(err error) tea.Msg { - return descEditDoneMsg{err: err, tempFile: tmpPath} - })() +func SetDebugLog(path string) error { + if debugFile != nil { + debugFile.Close() + debugFile = nil + debugWriter = nil + } + + if path == "" { + return nil + } + + f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644) + if err != nil { + return err } + debugFile = f + debugWriter = f + return nil } ``` @@ -151,13 +148,13 @@ func editDescriptionCmd(description string) tea.Cmd { ### rexfiles -* ๐ป Languages: Shell (34.7%), Perl (32.8%), Config (8.4%), CSS (8.2%), TOML (7.3%), Ruby (6.0%), Lua (1.8%), JSON (0.7%), INI (0.2%) +* ๐ป Languages: Perl (38.2%), Shell (30.6%), Config (8.0%), CSS (7.9%), TOML (7.0%), Ruby (5.7%), Lua (1.7%), JSON (0.7%), INI (0.1%) * ๐ Documentation: Text (97.3%), Markdown (2.7%) -* ๐ Commits: 875 -* ๐ Lines of Code: 3956 +* ๐ Commits: 876 +* ๐ Lines of Code: 4123 * ๐ Lines of Documentation: 854 -* ๐
Development Period: 2021-12-28 to 2025-07-09 -* ๐ฅ Recent Activity: 16.4 days (avg. age of last 42 commits) +* ๐
Development Period: 2021-12-28 to 2025-07-12 +* ๐ฅ Recent Activity: 18.2 days (avg. age of last 42 commits) * โ๏ธ License: No license found * ๐งช Status: Experimental (no releases yet) @@ -169,12 +166,19 @@ The project consists of three main components: **dotfiles** management for perso => https://codeberg.org/snonux/rexfiles View on Codeberg => https://github.com/snonux/rexfiles View on GitHub -Shell from `frontends/scripts/sitestats.sh`: +Perl from `frontends/scripts/foostats.pl`: ```AUTO -STATSFILE=/tmp/sitestats.csv -BOTSFILE=/tmp/sitebots.txt -TOP=20 +sub write ( $path, $content ) { + open my $fh, '>', "$path.tmp" + or die "\nCannot open file: $!"; + print $fh $content; + close $fh; + + rename + "$path.tmp", + $path; +} ``` --- @@ -187,7 +191,7 @@ TOP=20 * ๐ Lines of Code: 20091 * ๐ Lines of Documentation: 5674 * ๐
Development Period: 2020-01-09 to 2025-06-20 -* ๐ฅ Recent Activity: 52.4 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 55.1 days (avg. age of last 42 commits) * โ๏ธ License: Apache-2.0 * ๐ท๏ธ Latest Release: v4.2.0 (2023-06-21) * ๐ค AI-Assisted: This project was partially created with the help of generative AI @@ -204,37 +208,58 @@ The system uses a client-server architecture where dtail servers run on target m => https://codeberg.org/snonux/dtail View on Codeberg => https://github.com/snonux/dtail View on GitHub -Go from `internal/io/signal/signal.go`: +Go from `internal/mapr/groupset.go`: ```AUTO -func InterruptCh(ctx context.Context) <-chan string { - sigIntCh := make(chan os.Signal, 10) - gosignal.Notify(sigIntCh, os.Interrupt) - sigOtherCh := make(chan os.Signal, 10) - gosignal.Notify(sigOtherCh, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGQUIT) - statsCh := make(chan string) - - go func() { - for { - select { - case <-sigIntCh: - select { - case statsCh <- "Hint: Hit Ctrl+C again to exit": - select { - case <-sigIntCh: - os.Exit(0) - case <-time.After(time.Second * time.Duration(config.InterruptTimeoutS)): - } - default: - } - case <-sigOtherCh: - os.Exit(0) - case <-ctx.Done(): - return - } - } - }() - return statsCh +func NewGroupSet() *GroupSet { + g := GroupSet{} + g.InitSet() + return &g +} +``` + +--- + +### ior + +* ๐ป Languages: Go (81.0%), Raku (11.5%), C (4.4%), Make (1.7%), C/C++ (1.5%) +* ๐ Documentation: Text (63.6%), Markdown (36.4%) +* ๐ Commits: 330 +* ๐ Lines of Code: 7911 +* ๐ Lines of Documentation: 742 +* ๐
Development Period: 2024-01-18 to 2025-07-12 +* ๐ฅ Recent Activity: 55.8 days (avg. age of last 42 commits) +* โ๏ธ License: No license found +* ๐งช Status: Experimental (no releases yet) +* ๐ค AI-Assisted: This project was partially created with the help of generative AI + + +=> showcase/ior/image-1.png ior screenshot + +Based on my analysis of the codebase, here's a comprehensive summary of the I/O Riot NG (ior) project: + +=> showcase/ior/image-2.svg ior screenshot + +**I/O Riot NG** is a Linux-based performance monitoring tool that uses eBPF (extended Berkeley Packet Filter) to trace synchronous I/O system calls and analyze their execution times. This tool is particularly valuable for system performance analysis, allowing developers and system administrators to visualize I/O bottlenecks through detailed flamegraphs. It serves as a modern successor to the original I/O Riot project, migrating from SystemTap/C to a Go/C/BPF implementation for better performance and maintainability. + +The architecture combines kernel-level tracing with user-space analysis: eBPF programs (`internal/c/ior.bpf.c`) attach to kernel tracepoints to capture syscall entry/exit events, which are then processed by a Go-based event loop (`internal/eventloop.go`) that correlates enter/exit pairs, tracks file descriptors, and measures timing. The tool can operate in real-time mode for live monitoring or post-processing mode to generate flamegraphs from previously collected data using the Inferno flamegraph library. Key features include filtering capabilities for specific processes or file patterns, comprehensive statistics collection, and support for various I/O syscalls like open, read, write, close, and dup operations. + +=> https://codeberg.org/snonux/ior View on Codeberg +=> https://github.com/snonux/ior View on GitHub + +Go from `internal/file/file.go`: + +```AUTO +func NewFd(fd int32, name []byte, flags int32) FdFile { + f := FdFile{ + fd: fd, + name: types.StringValue(name), + flags: Flags(flags), + } + if f.flags == -1 { + panic(fmt.Sprintf("DEBUG with -1 flags: %v", f)) + } + return f } ``` @@ -248,7 +273,7 @@ func InterruptCh(ctx context.Context) <-chan string { * ๐ Lines of Code: 396 * ๐ Lines of Documentation: 24 * ๐
Development Period: 2025-04-18 to 2025-05-11 -* ๐ฅ Recent Activity: 71.7 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 74.4 days (avg. age of last 42 commits) * โ๏ธ License: Custom License * ๐ท๏ธ Latest Release: v1.0.0 (2025-05-11) @@ -273,50 +298,6 @@ def initialize(myself) --- -### ior - -* ๐ป Languages: C (54.7%), Go (37.4%), Raku (5.4%), Make (1.4%), C/C++ (1.1%) -* ๐ Documentation: Text (84.1%), Markdown (15.9%) -* ๐ Commits: 316 -* ๐ Lines of Code: 9835 -* ๐ Lines of Documentation: 559 -* ๐
Development Period: 2024-01-18 to 2025-06-14 -* ๐ฅ Recent Activity: 83.7 days (avg. age of last 42 commits) -* โ๏ธ License: No license found -* ๐งช Status: Experimental (no releases yet) - - -=> showcase/ior/image-1.png ior screenshot - -Based on my analysis of the codebase, here's a comprehensive summary of the I/O Riot NG (ior) project: - -=> showcase/ior/image-2.svg ior screenshot - -**I/O Riot NG** is a Linux-based performance monitoring tool that uses eBPF (extended Berkeley Packet Filter) to trace synchronous I/O system calls and analyze their execution times. This tool is particularly valuable for system performance analysis, allowing developers and system administrators to visualize I/O bottlenecks through detailed flamegraphs. It serves as a modern successor to the original I/O Riot project, migrating from SystemTap/C to a Go/C/BPF implementation for better performance and maintainability. - -The architecture combines kernel-level tracing with user-space analysis: eBPF programs (`internal/c/ior.bpf.c`) attach to kernel tracepoints to capture syscall entry/exit events, which are then processed by a Go-based event loop (`internal/eventloop.go`) that correlates enter/exit pairs, tracks file descriptors, and measures timing. The tool can operate in real-time mode for live monitoring or post-processing mode to generate flamegraphs from previously collected data using the Inferno flamegraph library. Key features include filtering capabilities for specific processes or file patterns, comprehensive statistics collection, and support for various I/O syscalls like open, read, write, close, and dup operations. - -=> https://codeberg.org/snonux/ior View on Codeberg -=> https://github.com/snonux/ior View on GitHub - -C from `tools/forktest.c`: - -```AUTO -int main() { - int fd = open("testfile", O_WRONLY| O_CREAT, 0644); - if (fd < 0) { - perror("open"); - return 1; - } - int flags = fcntl(fd, F_GETFL); - printf("Parent: File access mode is O_RDWR|O_CREAT (%d %d %d)\n", flags, - O_RDWR|O_CREAT, O_WRONLY|O_CREAT); - - pid_t pid = fork(); -``` - ---- - ### ds-sim * ๐ป Languages: Java (98.9%), Shell (0.6%), CSS (0.5%) @@ -325,7 +306,7 @@ int main() { * ๐ Lines of Code: 25762 * ๐ Lines of Documentation: 3101 * ๐
Development Period: 2008-05-15 to 2025-06-27 -* ๐ฅ Recent Activity: 85.0 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 87.8 days (avg. age of last 42 commits) * โ๏ธ License: Custom License * ๐งช Status: Experimental (no releases yet) * ๐ค AI-Assisted: This project was partially created with the help of generative AI @@ -340,28 +321,12 @@ The project is built on an event-driven architecture with clear component separa => https://codeberg.org/snonux/ds-sim View on Codeberg => https://github.com/snonux/ds-sim View on GitHub -Java from `src/main/java/simulator/VSCreateTask.java`: +Java from `src/main/java/testing/HeadlessLoader.java`: ```AUTO -private String eventClassname; - -private String menuText; - -private String protocolClassname; - -private String shortname; - -private boolean isProtocolActivation; - -private boolean isProtocolDeactivation; - -private boolean isClientProtocol; - -private boolean isRequest; - -public VSCreateTask(String menuText, String eventClassname) { - this.menuText = menuText; - this.eventClassname = eventClassname; +static { + System.setProperty("java.awt.headless", "true"); + System.setProperty("ds.sim.headless", "true"); } ``` @@ -375,7 +340,7 @@ public VSCreateTask(String menuText, String eventClassname) { * ๐ Lines of Code: 33 * ๐ Lines of Documentation: 3 * ๐
Development Period: 2025-04-03 to 2025-04-03 -* ๐ฅ Recent Activity: 97.6 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 100.3 days (avg. age of last 42 commits) * โ๏ธ License: No license found * ๐งช Status: Experimental (no releases yet) @@ -405,7 +370,7 @@ func main() { * ๐ Lines of Code: 3967 * ๐ Lines of Documentation: 411 * ๐
Development Period: 2024-05-04 to 2025-06-12 -* ๐ฅ Recent Activity: 114.5 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 117.3 days (avg. age of last 42 commits) * โ๏ธ License: Custom License * ๐ท๏ธ Latest Release: v1.0.0 (2025-03-04) * ๐ค AI-Assisted: This project was partially created with the help of generative AI @@ -422,16 +387,27 @@ The tool is architected around a file-based queueing system where posts progress => https://codeberg.org/snonux/gos View on Codeberg => https://github.com/snonux/gos View on GitHub -Go from `internal/platforms/linkedin/linkedin.go`: +Go from `internal/summary/summary.go`: ```AUTO -func postImageToLinkedInAPI(ctx context.Context, personURN, accessToken, - imagePath string) (string, error) { - uploadURL, imageURN, err := initializeImageUpload(ctx, personURN, accessToken) +func Run(ctx context.Context, args config.Args) error { + entries, err := deduppedEntries(args) if err != nil { - return imageURN, err + return err } - return imageURN, performImageUpload(ctx, imagePath, uploadURL, accessToken) + + sort.Slice(entries, func(i, j int) bool { + return entries[i].Time.Before(entries[j].Time) + }) + + title := fmt.Sprintf("Posts for %s", strings.Join(args.GeminiSummaryFor, " ")) + gemtext, err := fmt.Print(generateGemtext(args, entries, title)) + if err != nil { + return err + } + fmt.Println(gemtext) + + return nil } ``` @@ -441,13 +417,13 @@ func postImageToLinkedInAPI(ctx context.Context, personURN, accessToken, * ๐ป Languages: Perl (100.0%) * ๐ Documentation: Markdown (85.1%), Text (14.9%) -* ๐ Commits: 68 -* ๐ Lines of Code: 1556 +* ๐ Commits: 70 +* ๐ Lines of Code: 1586 * ๐ Lines of Documentation: 154 -* ๐
Development Period: 2023-01-02 to 2025-07-09 -* ๐ฅ Recent Activity: 128.9 days (avg. age of last 42 commits) +* ๐
Development Period: 2023-01-02 to 2025-07-12 +* ๐ฅ Recent Activity: 121.3 days (avg. age of last 42 commits) * โ๏ธ License: Custom License -* ๐งช Status: Experimental (no releases yet) +* ๐ท๏ธ Latest Release: v0.1.0 (2025-07-12) Based on the README and project structure, **foostats** is a privacy-respecting web analytics tool written in Perl specifically designed for OpenBSD systems. It processes both traditional HTTP/HTTPS logs and Gemini protocol logs to generate comprehensive traffic statistics while maintaining visitor privacy through SHA3-512 IP hashing. The tool is built for the foo.zone ecosystem and similar sites that need analytics without compromising user privacy. @@ -482,7 +458,7 @@ sub write ( $path, $content ) { * ๐ Lines of Code: 1373 * ๐ Lines of Documentation: 48 * ๐
Development Period: 2024-12-05 to 2025-02-28 -* ๐ฅ Recent Activity: 138.3 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 141.1 days (avg. age of last 42 commits) * โ๏ธ License: Custom License * ๐งช Status: Experimental (no releases yet) @@ -494,52 +470,44 @@ The system is implemented with a modular architecture centered around a DSL clas => https://codeberg.org/snonux/rcm View on Codeberg => https://github.com/snonux/rcm View on GitHub -Ruby from `lib/dslkeywords/package.rb`: - -```AUTO -def package(name, &block) - return unless @conds_met - - f = Package.new(name) - f.packages(f.instance_eval(&block)) - self << f - f -``` - ---- - -### gemtexter - -* ๐ป Languages: Shell (68.1%), CSS (28.7%), Config (1.9%), HTML (1.3%) -* ๐ Documentation: Text (76.1%), Markdown (23.9%) -* ๐ Commits: 465 -* ๐ Lines of Code: 2268 -* ๐ Lines of Documentation: 1180 -* ๐
Development Period: 2021-05-21 to 2025-07-09 -* ๐ฅ Recent Activity: 200.7 days (avg. age of last 42 commits) -* โ๏ธ License: GPL-3.0 -* ๐ท๏ธ Latest Release: 3.0.0 (2024-10-01) - - -**Gemtexter** is a static site generator and blog engine that transforms content written in Gemini Gemtext format into multiple output formats. It's a comprehensive Bash-based tool designed to support the Gemini protocol (a simpler alternative to HTTP) while maintaining compatibility with traditional web technologies. The project converts a single source of Gemtext content into HTML (XHTML 1.0 Transitional), Markdown, and native Gemtext formats, enabling authors to write once and publish across multiple platforms including Gemini capsules, traditional websites, and GitHub/Codeberg pages. - -The implementation is built entirely in Bash (version 5.x+) using a modular library approach with separate source files for different functionality (atomfeed, gemfeed, HTML generation, Markdown conversion, templating, etc.). Key features include automatic blog post indexing, Atom feed generation, customizable HTML themes, source code highlighting, Bash-based templating system, and integrated Git workflow management. The architecture separates content directories by format (gemtext/, html/, md/) and includes comprehensive theming support, font embedding, and publishing workflows that can automatically sync content to multiple Git repositories for deployment on various platforms. - -=> https://codeberg.org/snonux/gemtexter View on Codeberg -=> https://github.com/snonux/gemtexter View on GitHub - -Shell from `lib/generate.source.sh`: +Ruby from `lib/dslkeywords/file.rb`: ```AUTO -done < <(find "$CONTENT_BASE_DIR/gemtext" -type f -name \*.gmi) - -wait -log INFO "Converted $num_gmi_files Gemtext files" - -log VERBOSE "Adding other docs to $*" - -while read -r src; do - num_doc_files=$(( num_doc_files + 1 )) +def mode(what) = @mode = what +def owner(what) = @owner = what +def group(what) = @group = what + +def evaluate! + unless super + @mode = nil + return false + end + true +end + +def content(text = nil) + if text.nil? + text = @from == :sourcefile ? ::File.read(@content) : @content + return @from == :template ? ERB.new(text).result : text + end + @content = text.instance_of?(Array) ? text.join("\n") : text +end + +protected + +def permissions!(file_path = path) + return unless ::File.exist?(file_path) + + stat = ::File.stat(file_path) + set_mode!(stat) + set_owner!(stat) +end + +def validate(method, what, *valids) + return what if valids.include?(what) + + raise UnsupportedOperation, + "Unsupported '#{method}' operation #{what} (#{what.class})" ``` --- @@ -552,7 +520,7 @@ while read -r src; do * ๐ Lines of Code: 917 * ๐ Lines of Documentation: 33 * ๐
Development Period: 2024-01-20 to 2025-07-06 -* ๐ฅ Recent Activity: 448.3 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 451.0 days (avg. age of last 42 commits) * โ๏ธ License: MIT * ๐ท๏ธ Latest Release: v0.0.3 (2025-07-06) @@ -623,7 +591,7 @@ func createPreferenceWindow(a fyne.App) fyne.Window { * ๐ Lines of Code: 12 * ๐ Lines of Documentation: 3 * ๐
Development Period: 2024-03-24 to 2024-03-24 -* ๐ฅ Recent Activity: 472.1 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 474.9 days (avg. age of last 42 commits) * โ๏ธ License: Custom License * ๐งช Status: Experimental (no releases yet) @@ -660,7 +628,7 @@ aws: build * ๐ Lines of Code: 2850 * ๐ Lines of Documentation: 52 * ๐
Development Period: 2023-08-27 to 2025-04-05 -* ๐ฅ Recent Activity: 502.1 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 504.9 days (avg. age of last 42 commits) * โ๏ธ License: MIT * ๐งช Status: Experimental (no releases yet) @@ -672,17 +640,89 @@ The system is designed to host multiple personal services including Anki sync se => https://codeberg.org/snonux/terraform View on Codeberg => https://github.com/snonux/terraform View on GitHub -HCL from `s3-org-buetow-tfstate/main.tf`: +HCL from `org-buetow-eks/remotestates.tf`: ```AUTO -terraform { - backend "s3" { +data "terraform_remote_state" "base" { + backend = "s3" + config = { bucket = "org-buetow-tfstate" - key = "s3-org-buetow-tfstate/terraform.tfstate" + key = "org-buetow-base/terraform.tfstate" region = "eu-central-1" - encrypt = true } } + +data "terraform_remote_state" "elb" { +``` + +--- + +### gogios + +* ๐ป Languages: Go (94.4%), YAML (3.4%), JSON (2.2%) +* ๐ Documentation: Markdown (100.0%) +* ๐ Commits: 77 +* ๐ Lines of Code: 1096 +* ๐ Lines of Documentation: 287 +* ๐
Development Period: 2023-04-17 to 2025-06-12 +* ๐ฅ Recent Activity: 517.7 days (avg. age of last 42 commits) +* โ๏ธ License: Custom License +* ๐ท๏ธ Latest Release: v1.1.0 (2024-05-03) +* ๐ค AI-Assisted: This project was partially created with the help of generative AI + + +=> showcase/gogios/image-1.png gogios screenshot + +Gogios is a lightweight, minimalistic monitoring tool written in Go designed for small-scale server monitoring. It executes standard Nagios-compatible check plugins and sends email notifications only when service states change, making it ideal for personal infrastructure or small environments with limited resources. The tool emphasizes simplicity over complexity, avoiding the bloat of enterprise monitoring solutions like Nagios, Icinga, or Prometheus by eliminating features like web UIs, databases, contact groups, and clustering. + +The implementation follows a clean architecture with concurrent check execution, dependency management, and persistent state tracking. Key features include state-based notifications (only alerts on status changes), configurable retry logic, federation support for distributed monitoring, and stale detection for checks that haven't run recently. The tool is configured via JSON and requires only a local mail transfer agent for notifications. It's designed to run via cron jobs and supports high-availability setups through simple dual-server configurations, making it perfect for users who want effective monitoring without operational overhead. + +=> https://codeberg.org/snonux/gogios View on Codeberg +=> https://github.com/snonux/gogios View on GitHub + +Go from `internal/state.go`: + +```AUTO +func newState(conf config) (state, error) { + s := state{ + stateFile: fmt.Sprintf("%s/state.json", conf.StateDir), + checks: make(map[string]checkState), + staleEpoch: time.Now().Unix() - int64(conf.StaleThreshold), + } + + if _, err := os.Stat(s.stateFile); err != nil { + return s, nil + } + + file, err := os.Open(s.stateFile) + if err != nil { + return s, err + } + defer file.Close() + + bytes, err := io.ReadAll(file) + if err != nil { + return s, err + } + + if err := json.Unmarshal(bytes, &s.checks); err != nil { + return s, err + } + + var obsolete []string + for name := range s.checks { + if _, ok := conf.Checks[name]; !ok { + obsolete = append(obsolete, name) + } + } + + for _, name := range obsolete { + delete(s.checks, name) + log.Printf("State of %s is obsolete (removed)", name) + } + + return s, nil +} ``` --- @@ -695,7 +735,7 @@ terraform { * ๐ Lines of Code: 32 * ๐ Lines of Documentation: 3 * ๐
Development Period: 2023-12-31 to 2023-12-31 -* ๐ฅ Recent Activity: 555.7 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 558.4 days (avg. age of last 42 commits) * โ๏ธ License: No license found * ๐งช Status: Experimental (no releases yet) @@ -732,7 +772,7 @@ run: build * ๐ Lines of Code: 29 * ๐ Lines of Documentation: 3 * ๐
Development Period: 2023-08-13 to 2024-01-01 -* ๐ฅ Recent Activity: 648.9 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 651.6 days (avg. age of last 42 commits) * โ๏ธ License: MIT * ๐งช Status: Experimental (no releases yet) @@ -770,7 +810,7 @@ aws: * ๐ Lines of Code: 1525 * ๐ Lines of Documentation: 15 * ๐
Development Period: 2023-04-17 to 2023-11-19 -* ๐ฅ Recent Activity: 701.0 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 703.8 days (avg. age of last 42 commits) * โ๏ธ License: Custom License * ๐งช Status: Experimental (no releases yet) @@ -782,15 +822,33 @@ The architecture consists of several key components: a quorum manager that handl => https://codeberg.org/snonux/gorum View on Codeberg => https://github.com/snonux/gorum View on GitHub -Go from `internal/utils/string.go`: +Go from `internal/notifier/email.go`: ```AUTO - "strings" -) +func (em email) send(conf config.Config) error { + if !conf.EmailNotifycationEnabled() { + return nil + } + log.Println("notify:", em.subject, em.body) + + headers := map[string]string{ + "From": conf.EmailFrom, + "To": conf.EmailTo, + "Subject": em.subject, + "MIME-Version": "1.0", + "Content-Type": "text/plain; charset=\"utf-8\"", + } + + header := "" + for k, v := range headers { + header += fmt.Sprintf("%s: %s\r\n", k, v) + } + + message := header + "\r\n" + em.body + log.Println("Using SMTP server", conf.SMTPServer) -func StripPort(addr string) string { - parts := strings.Split(addr, ":") - return parts[0] + return smtp.SendMail(conf.SMTPServer, nil, conf.EmailFrom, + []string{conf.EmailTo}, []byte(message)) } ``` @@ -804,7 +862,7 @@ func StripPort(addr string) string { * ๐ Lines of Code: 312 * ๐ Lines of Documentation: 416 * ๐
Development Period: 2013-03-22 to 2025-05-18 -* ๐ฅ Recent Activity: 751.1 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 753.8 days (avg. age of last 42 commits) * โ๏ธ License: No license found * ๐ท๏ธ Latest Release: v1.0.0 (2023-04-29) @@ -839,75 +897,6 @@ method output-trim(Str \str, UInt \line-limit --> Str) { --- -### gogios - -* ๐ป Languages: Go (90.8%), YAML (5.6%), JSON (3.6%) -* ๐ Documentation: Markdown (100.0%) -* ๐ Commits: 77 -* ๐ Lines of Code: 662 -* ๐ Lines of Documentation: 195 -* ๐
Development Period: 2023-04-17 to 2024-05-03 -* ๐ฅ Recent Activity: 762.0 days (avg. age of last 42 commits) -* โ๏ธ License: Custom License -* ๐ท๏ธ Latest Release: v1.1.0 (2024-05-03) - -โ ๏ธ **Notice**: This project appears to be finished, obsolete, or no longer maintained. Last meaningful activity was over 2 years ago. Use at your own risk. - -=> showcase/gogios/image-1.png gogios screenshot - -Gogios is a lightweight, minimalistic monitoring tool written in Go designed for small-scale server monitoring. It executes standard Nagios-compatible check plugins and sends email notifications only when service states change, making it ideal for personal infrastructure or small environments with limited resources. The tool emphasizes simplicity over complexity, avoiding the bloat of enterprise monitoring solutions like Nagios, Icinga, or Prometheus by eliminating features like web UIs, databases, contact groups, and clustering. - -The implementation follows a clean architecture with concurrent check execution, dependency management, and persistent state tracking. Key features include state-based notifications (only alerts on status changes), configurable retry logic, federation support for distributed monitoring, and stale detection for checks that haven't run recently. The tool is configured via JSON and requires only a local mail transfer agent for notifications. It's designed to run via cron jobs and supports high-availability setups through simple dual-server configurations, making it perfect for users who want effective monitoring without operational overhead. - -=> https://codeberg.org/snonux/gogios View on Codeberg -=> https://github.com/snonux/gogios View on GitHub - -Go from `internal/state.go`: - -```AUTO -func readState(conf config) (state, error) { - s := state{ - stateFile: fmt.Sprintf("%s/state.json", conf.StateDir), - checks: make(map[string]checkState), - } - - if _, err := os.Stat(s.stateFile); err != nil { - return s, nil - } - - file, err := os.Open(s.stateFile) - if err != nil { - return s, err - } - defer file.Close() - - bytes, err := io.ReadAll(file) - if err != nil { - return s, err - } - - if err := json.Unmarshal(bytes, &s.checks); err != nil { - return s, err - } - - var obsolete []string - for name := range s.checks { - if _, ok := conf.Checks[name]; !ok { - obsolete = append(obsolete, name) - } - } - - for _, name := range obsolete { - delete(s.checks, name) - log.Printf("State of %s is obsolete (removed)", name) - } - - return s, nil -} -``` - ---- - ### randomjournalpage * ๐ป Languages: Shell (94.1%), Make (5.9%) @@ -916,7 +905,7 @@ func readState(conf config) (state, error) { * ๐ Lines of Code: 51 * ๐ Lines of Documentation: 26 * ๐
Development Period: 2022-06-02 to 2024-04-20 -* ๐ฅ Recent Activity: 765.8 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 768.5 days (avg. age of last 42 commits) * โ๏ธ License: No license found * ๐งช Status: Experimental (no releases yet) @@ -941,6 +930,44 @@ declare -i NUM_PAGES_TO_EXTRACT=42 # This is the answear! --- +### gemtexter + +* ๐ป Languages: Shell (85.6%), CSS (9.0%), Config (3.3%), HTML (2.1%) +* ๐ Documentation: Text (71.7%), Markdown (28.3%) +* ๐ Commits: 465 +* ๐ Lines of Code: 1451 +* ๐ Lines of Documentation: 738 +* ๐
Development Period: 2021-05-21 to 2023-03-31 +* ๐ฅ Recent Activity: 853.0 days (avg. age of last 42 commits) +* โ๏ธ License: Custom License +* ๐ท๏ธ Latest Release: 3.0.0 (2024-10-01) + +โ ๏ธ **Notice**: This project appears to be finished, obsolete, or no longer maintained. Last meaningful activity was over 2 years ago. Use at your own risk. + +**Gemtexter** is a static site generator and blog engine that transforms content written in Gemini Gemtext format into multiple output formats. It's a comprehensive Bash-based tool designed to support the Gemini protocol (a simpler alternative to HTTP) while maintaining compatibility with traditional web technologies. The project converts a single source of Gemtext content into HTML (XHTML 1.0 Transitional), Markdown, and native Gemtext formats, enabling authors to write once and publish across multiple platforms including Gemini capsules, traditional websites, and GitHub/Codeberg pages. + +The implementation is built entirely in Bash (version 5.x+) using a modular library approach with separate source files for different functionality (atomfeed, gemfeed, HTML generation, Markdown conversion, templating, etc.). Key features include automatic blog post indexing, Atom feed generation, customizable HTML themes, source code highlighting, Bash-based templating system, and integrated Git workflow management. The architecture separates content directories by format (gemtext/, html/, md/) and includes comprehensive theming support, font embedding, and publishing workflows that can automatically sync content to multiple Git repositories for deployment on various platforms. + +=> https://codeberg.org/snonux/gemtexter View on Codeberg +=> https://github.com/snonux/gemtexter View on GitHub + +Shell from `lib/html.source.sh`: + +```AUTO + done < <(find "$html_base_dir" -mindepth 1 -maxdepth 1 -type d | $GREP -E + -v '(\.git)') + cp "$HTML_WEBFONT_TEXT" "$html_base_dir/text.ttf" + cp "$HTML_WEBFONT_CODE" "$html_base_dir/code.ttf" + cp "$HTML_WEBFONT_HANDNOTES" "$html_base_dir/handnotes.ttf" + cp "$HTML_WEBFONT_TYPEWRITER" "$html_base_dir/typewriter.ttf" +} + +html::fromgmi () { + local is_list=no +``` + +--- + ### sway-autorotate * ๐ป Languages: Shell (100.0%) @@ -949,7 +976,7 @@ declare -i NUM_PAGES_TO_EXTRACT=42 # This is the answear! * ๐ Lines of Code: 41 * ๐ Lines of Documentation: 17 * ๐
Development Period: 2020-01-30 to 2025-04-30 -* ๐ฅ Recent Activity: 1059.3 days (avg. age of last 42 commits) +* ๐ฅ Recent Activity: 1062.1 days (avg. age of last 42 commits) * โ๏ธ License: GPL-3.0 * ๐งช Status: Experimental (no releases yet) @@ -975,48 +1002,6 @@ declare -r SCREEN=eDP-1 --- -### photoalbum - -* ๐ป Languages: Shell (80.1%), Make (12.3%), Config (7.6%) -* ๐ Documentation: Markdown (100.0%) -* ๐ Commits: 153 -* ๐ Lines of Code: 342 -* ๐ Lines of Documentation: 39 -* ๐
Development Period: 2011-11-19 to 2022-04-02 -* ๐ฅ Recent Activity: 1278.9 days (avg. age of last 42 commits) -* โ๏ธ License: No license found -* ๐ท๏ธ Latest Release: 0.5.0 (2022-02-21) - -โ ๏ธ **Notice**: This project appears to be finished, obsolete, or no longer maintained. Last meaningful activity was over 2 years ago. Use at your own risk. - -PhotoAlbum is a minimal Bash script for Unix-like systems that generates static web photo albums from directories of images. It creates pure HTML+CSS galleries without JavaScript, making them lightweight and universally compatible. The tool is designed for simplicity and portability - users point it at a directory of photos, configure basic settings like thumbnail size and gallery title, and it automatically generates a complete static website with image previews, navigation, and optional download archives. - -The implementation centers around a single Bash script (`photoalbum.sh`) that uses ImageMagick's `convert` command to generate thumbnails and resized images, then applies customizable HTML templates to create the gallery structure. The architecture separates configuration (via `photoalbumrc` files), templating (modular `.tmpl` files for different page components), and processing logic, allowing users to customize the appearance while maintaining the core functionality. The generated output is a self-conta |
