goget
Go CLI Networking HTTP/FTP
MIT

O projektu

CLI download utility à la curl/wget napsaná v čistém Go. Žádné externí závislosti mimo standardní knihovnu a golang.org/x — žádný vendor bloat. Podporuje paralelní stahování, resume přerušených přenosů, ověřování checksumů a Metalink mirroring. IPv6-first síťový stack s fallbackem na IPv4.

Architektura

Jádro staví na net/http s custom transportem pro paralelní chunked download. Každý chunk je stahován v samostatné goroutine s využitím sync.WaitGroup a errgroup. Checksum verifikace podporuje SHA-256, SHA-512, BLAKE2b a SHA-3 přes crypto balíček. Metalink parser je implementován od nuly s podporou mirror selection a failoveru. Rate limiting přes token bucket algoritmus.

$ cat ~/goget/internal/download/parallel.go
// goget – parallel chunked download with checksum verification package download import ( "context" "crypto/sha256" "fmt" "io" "net/http" "os" "sync" "golang.org/x/sync/errgroup" ) const chunkSize = 8 << 20 // 8 MiB type ParallelDownloader struct { Client *http.Client Workers int Checksum string // expected SHA-256 hex } func (d *ParallelDownloader) Download(ctx context.Context, url, dst string, size int64) error { if size <= 0 { return fmt.Errorf("goget: server did not report content-length; use --single") } chunks := splitRanges(size, chunkSize) file, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE, 0644) if err != nil { return err } defer file.Close() var progress int64 var mu sync.Mutex hasher := sha256.New() g, ctx := errgroup.WithContext(ctx) g.SetLimit(d.Workers) for _, r := range chunks { r := r g.Go(func() error { req, _ := http.NewRequestWithContext(ctx, "GET", url, nil) req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", r.start, r.end)) resp, err := d.Client.Do(req) if err != nil { return err } defer resp.Body.Close() buf := make([]byte, 32<<10) for { n, err := resp.Body.Read(buf) if n > 0 { file.WriteAt(buf[:n], r.offset) r.offset += int64(n) mu.Lock() hasher.Write(buf[:n]) progress += int64(n) mu.Unlock() } if err == io.EOF { break } if err != nil { return err } } return nil }) } if err := g.Wait(); err != nil { return err } if d.Checksum != "" && fmt.Sprintf("%x", hasher.Sum(nil)) != d.Checksum { return fmt.Errorf("goget: checksum mismatch – file may be corrupted") } return nil }

Klíčové vlastnosti

  • Paralelní chunked download s konfigurovatelným počtem workerů
  • Resume přerušených stahování — detekce existujícího souboru a Range request
  • Podpora HTTP, HTTPS, FTP a FTPS přes standardní knihovnu
  • Checksum verifikace: SHA-256, SHA-512, BLAKE2b, SHA-3
  • Metalink podpora s mirror selectionem a automatickým failoverem
  • Queue management — fronta URL s prioritami a paralelním zpracováním
  • IPv6-first síťování s Happy Eyeballs (RFC 8305)
  • Zero external dependencies — pouze stdlib + golang.org/x

flumen
Rust BitTorrent Iced GUI P2P
BSD-3-Clause

O projektu

Moderní BitTorrent klient s nativním Iced GUI napsaný v čistém Rustu. Žádný Electron, žádné webové technologie v UI — jen nativní výkon a bezpečnost paměti. Podporuje široké spektrum platforem: Ubuntu, Deepin, openEuler a FreeBSD na AMD64, ARM64, RISC-V a LoongArch architekturách. Distribuován jako .deb, AppImage a FreeBSD balíček.

Architektura

Asynchronní jádro postavené na Tokio runtime. Implementuje uTP (BEP 29) s LEDBAT congestion control pro nízkoprioritní přenosy, DHT (BEP 5) pro decentralizované peer discovery, PEX (BEP 11) pro výměnu peerů mezi klienty a MSE/PE šifrování (BEP 10). Piece selection používá rarest-first algoritmus s endgame modem pro dokončovací fázi. Rate limiting přes token-bucket. UPnP/NAT-PMP pro automatické port forwarding. SHA-1 verifikace integrity dat. GUI staví na knihovně cardo pro themed widgety — dark/light/system theme, torrent list s vyhledáváním a řazením, sidebar s badge counts, detail panel s ETA, system tray přes D-Bus StatusNotifierItem.

$ cat ~/flumen/src/piece/picker.rs
// flumen – rarest-first piece picker with endgame mode use std::collections::{HashMap, HashSet}; pub struct PiecePicker { total: usize, have: HashSet<usize>, peer_has: HashMap<usize, usize>, // piece index → peer count endgame: bool, requested: HashSet<usize>, } impl PiecePicker { pub fn new(total: usize) -> Self { let mut peer_has = HashMap::with_capacity(total); for i in 0..total { peer_has.insert(i, 0); } Self { total, have: HashSet::new(), peer_has, endgame: false, requested: HashSet::new() } } pub fn update_peer(&mut self, bitfield: &[bool]) { for (i, has) in bitfield.iter().enumerate() { if *has && !self.have.contains(&i) { *self.peer_has.get_mut(&i).unwrap() += 1; } } } pub fn next_piece(&mut self, peer_pieces: &HashSet<usize>) -> Option<usize> { let remaining: usize = self.total - self.have.len(); if remaining == 0 { return None; } // Enter endgame when few pieces remain if remaining <= 10 && !self.endgame { self.endgame = true; self.requested.clear(); } if self.endgame { // Endgame: request from all peers simultaneously peer_pieces.iter() .filter(|p| !self.have.contains(p)) .next().copied() } else { // Rarest-first: pick piece with fewest peers peer_pieces.iter() .filter(|p| !self.have.contains(p) && !self.requested.contains(p)) .min_by_key(|p| self.peer_has.get(p).unwrap_or(&0)) .copied() .inspect(|p| { self.requested.insert(*p); }) } } }

Klíčové vlastnosti

  • uTP (BEP 29) s LEDBAT congestion control — nízká priorita, nezahlcuje síť
  • DHT (BEP 5) pro decentralizované vyhledávání peerů bez trackeru
  • PEX (BEP 11) — výměna peerů mezi klienty pro rychlejší swarm
  • MSE/PE šifrování (BEP 10) pro obfuskovaný přenos
  • UPnP/NAT-PMP pro automatické mapování portů
  • Rarest-first piece selection s endgame modem
  • Token-bucket rate limiting pro upload i download
  • Iced GUI s dark/light/system theme, vyhledáváním, řazením, ETA, system tray
  • Multi-platform: Ubuntu, Deepin, openEuler, FreeBSD (AMD64, ARM64, RISC-V, LoongArch)

web-games
HTML5 Canvas JavaScript Web Audio
BSD-3-Clause

O projektu

Kolekce 4 klasických arkádových her napsaných v čistém vanilla JavaScriptu. Žádné frameworky, knihovny ani build tooling — jen HTML5 Canvas, Web Audio API a CSS3. Hry běží okamžitě v prohlížeči bez instalace. Asteroidy (space shooter), Had (snake), Labyrint (maze), Tetromina (tetris). Lokalizace do češtiny a angličtiny, touch ovládání pro mobilní zařízení, high score přes localStorage, responzivní design a nastavitelná obtížnost.

Technické provedení

Každá hra je samostatný adresář s index.html, herní logikou a styly. Herní smyčka běží na requestAnimationFrame s fixním time stepem pro deterministickou fyziku. Vykreslování přes Canvas 2D API s double bufferingem pro plynulou animaci. Zvukové efekty přes Web Audio API s procedurálně generovanými tóny — žádné externí audio soubory. Touch ovládání přes touchstart/touchmove eventy s detekcí swipe gest.

$ cat ~/web-games/asteroidy/game.js
// Asteroidy – space shooter with Canvas 2D and Web Audio const W = 800, H = 600; const canvas = document.getElementById('c'); const ctx = canvas.getContext('2d'); const ac = new AudioContext(); let ship = { x: W/2, y: H/2, a: 0, vx: 0, vy: 0 }; let bullets = [], asteroids = [], score = 0, lives = 3; let keys = {}; function spawnAsteroid() { const edge = Math.random() * 4 | 0; let x, y; if (edge === 0) { x = 0; y = Math.random() * H; } else if (edge === 1) { x = W; y = Math.random() * H; } else if (edge === 2) { x = Math.random() * W; y = 0; } else { x = Math.random() * W; y = H; } const size = Math.random() * 30 + 15; asteroids.push({ x, y, size, vx: (Math.random()-0.5)*2, vy: (Math.random()-0.5)*2, vertices: Array.from({length:10}, () => Math.random()*0.4+0.6) }); } function beep(freq, dur, vol=0.1) { const osc = ac.createOscillator(); const gain = ac.createGain(); osc.connect(gain); gain.connect(ac.destination); osc.frequency.setValueAtTime(freq, ac.currentTime); gain.gain.setValueAtTime(vol, ac.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, ac.currentTime+dur); osc.start(); osc.stop(ac.currentTime+dur); } function update(dt) { // Ship thrust & rotation if (keys['ArrowLeft']) ship.a -= 0.005 * dt; if (keys['ArrowRight']) ship.a += 0.005 * dt; if (keys['ArrowUp']) { ship.vx += Math.cos(ship.a) * 0.1; ship.vy += Math.sin(ship.a) * 0.1; } ship.x = (ship.x + ship.vx + W) % W; ship.y = (ship.y + ship.vy + H) % H; // Collision detection: point-in-polygon approximation for (let i = asteroids.length-1; i >= 0; i--) { const a = asteroids[i]; const dx = ship.x - a.x, dy = ship.y - a.y; if (dx*dx + dy*dy < a.size*a.size) { lives--; asteroids.splice(i,1); beep(80,0.3); if (lives<=0) gameOver(); } } }

Klíčové vlastnosti

  • 4 klasické arkádové hry: Asteroidy, Had, Labyrint, Tetromina
  • 100% vanilla JS — žádné frameworky, knihovny ani build tools
  • Canvas 2D API s double bufferingem pro plynulou 60 FPS animaci
  • Web Audio API s procedurálně generovanými zvukovými efekty
  • Touch ovládání se swipe gesty pro mobilní zařízení
  • High score perzistence přes localStorage pro každou hru
  • Responzivní design a nastavitelná obtížnost
  • Živě na games.petrbalvin.org

cardo
Rust Iced 0.14 Widget Library GUI
BSD-3-Clause

O projektu

Custom widget knihovna pro Iced 0.14 — Rust GUI framework. Cardo poskytuje 25 plně tematizovaných widgetů připravených k okamžitému použití: tlačítka, slidery, switche, textová pole, pick listy, progress bary, badge, karty, taby, sidebar, modální okna, dialogy, tooltipy a context menu. Light/dark/auto theme s real-time detekcí změny přes OS. 40 vestavěných SVG ikon renderovaných přes currentColor. Animace s easing funkcemi a stavovým automatem Animator.

Architektura

Každý widget implementuje Iced Widget trait s vlastními State, Event a theme-aware render logikou. Theme systém používá Theme enum (Light/Dark/Auto) s detekcí OS přes dark-light crate. SVG ikony jsou embedované při compile-time přes include_str! a renderované do Iced Canvas nebo Svg handle. Animace běží na Animator state machine s podporou easing funkcí (ease-in, ease-out, ease-in-out, bounce, elastic) a automatickým request_redraw přes Iced window::frames subscription.

$ cat ~/cardo/src/widgets/button.rs
// cardo – themed CButton with animation and SVG icon support use iced::advanced::widget::{self, Widget}; use iced::{Element, Length, Renderer, Theme}; use crate::theme::{self, CardoTheme}; use crate::animation::{Animator, Easing}; use crate::icon::Icon; pub struct CButton<'a, Message> { label: String, icon: Option<Icon>, variant: ButtonVariant, on_press: Option<Message>, anim: Animator, _phantom: std::marker::PhantomData<&'a Message>, } pub enum ButtonVariant { Primary, Secondary, Ghost, Destructive } impl<'a, Message: 'a + Clone> CButton<'a, Message> { pub fn new(label: impl Into<String>) -> Self { Self { label: label.into(), icon: None, variant: ButtonVariant::Primary, on_press: None, anim: Animator::new(200, Easing::EaseOut), _phantom: std::marker::PhantomData, } } pub fn icon(mut self, icon: Icon) -> Self { self.icon = Some(icon); self } pub fn variant(mut self, v: ButtonVariant) -> Self { self.variant = v; self } pub fn on_press(mut self, msg: Message) -> Self { self.on_press = Some(msg); self } } impl<'a, Message: 'a + Clone> Widget<Message, Theme, Renderer> for CButton<'a, Message> { fn draw(&self, tree: &widget::Tree, renderer: &mut Renderer, theme: &Theme, _style: &widget::Style, layout: Layout, _cursor: iced::mouse::Cursor, _viewport: &Rectangle) { let cardo = CardoTheme::from_iced(theme); let colors = cardo.button_colors(self.variant); let bounds = layout.bounds(); let progress = self.anim.value(); // hover/press animation // Background with animated border radius + color blend let bg = colors.bg.mix(colors.hover, progress); renderer.fill_quad(iced::advanced::renderer::Quad { bounds, border_radius: cardo.radius_md(), ..Default::default() }, bg); // SVG icon (currentColor via cardo palette) if let Some(icon) = &self.icon { let icon_bounds = Rectangle { x: bounds.x + 12.0, y: bounds.center_y() - 8.0, width: 16.0, height: 16.0 }; icon.draw(renderer, icon_bounds, colors.fg); } // Label text let text_x = bounds.x + if self.icon.is_some() { 34.0 } else { 16.0 }; renderer.fill_text(self.label.as_str(), text_x, bounds.center_y(), colors.fg, cardo.font_size_md()); } } pub fn c_button<'a, Message: 'a + Clone>(label: impl Into<String>) -> CButton<'a, Message> { CButton::new(label) }

Klíčové vlastnosti

  • 25 tematizovaných widgetů: CButton, CSlider, CSwitch, CTextInput, CPickList, CProgressBar, CBadge, CCard, CTabs, CSidebar, CModal, CDialog, CTooltip, CContextMenu a další
  • Light/dark/auto theme s real-time OS detekcí přes dark-light crate
  • 40 vestavěných SVG ikon renderovaných přes currentColor
  • Animation framework s easing funkcemi (ease-in/out, bounce, elastic) a Animator state machine
  • Konzistentní design systém — barvy, zaoblení, spacing, typografie
Zpět nahoru