Commit graph

54 commits

Author SHA1 Message Date
65a6aad3ab Add i18n support with 20 languages and language chooser
- 20 languages: en, zh, es, hi, ar, pt, ru, ja, fr, de, ko, it, nl, pl, tr, vi, th, id, uk, sv
- Language dropdown in nav bar with native names (中文, 日本語, 한국어, etc.)
- Cookie persistence (lang cookie, 1 year expiry)
- localStorage backup (neopig_lang)
- Accept-Language header fallback for auto-detection
- All pages updated: search, crawl, live, view, page, phantom, about
2025-12-31 19:19:04 -05:00
007a390845 Fix: external links incorrectly rewritten to /view/ due to filename match
The filename fallback lookup was matching external links like
https://pypi.org/project/virt-back/ because the filename 'virt-back'
matched a media file in the database.

Now:
1. Filename fallback only applies to URLs with media extensions
2. href rewriting only applies to exact URI matches or media file URLs
3. External links are preserved as-is
2025-12-31 18:25:29 -05:00
75a9b27fae Fix: page media was filtering out all PNGs instead of just screenshots
Changed filter from mime_type != 'image/png' to media_type != 'screenshot'
2025-12-31 18:21:15 -05:00
b85d99a231 Show duration on completed crawl jobs 2025-12-31 18:13:15 -05:00
0a5762fbc4 Fix: header/logo images were not downloaded due to soup mutation
The page_content extraction was decomposing nav/header/footer from the
soup BEFORE media extraction, causing header/logo images to be missed.

Now uses a fresh BeautifulSoup parse of the body for text extraction,
preserving the original soup for media extraction.
2025-12-31 18:01:27 -05:00
2e48e83c9f Add formatBytes function to crawl UI 2025-12-31 17:49:30 -05:00
d8b44d4f21 Add error handling for job list JSON parsing to prevent silent failures 2025-12-31 17:41:46 -05:00
1e25c8d3d0 Default crawl mode to 'media' (all media) in UI 2025-12-31 17:38:38 -05:00
a3ad7abfb9 Fix crawl job stats: add screenshots, dupes, bytes to completed jobs 2025-12-31 17:36:09 -05:00
66538a6ab4 Add crawl ETA estimates to UI based on pages/sec rate 2025-12-31 16:19:13 -05:00
0bfc1a0292 Fix hash_to_path calls passing ext as depth parameter 2025-12-31 16:12:39 -05:00
24120ad867 Update README for filevault 2.0, remove storage.py refs, add depth docs 2025-12-31 16:06:11 -05:00
96a3c9c786 Update tests for filevault 2.0.0 API
- Rewrite test_filevault.py for new API (depth=9, hex pairs, content-addressable)
- Rewrite test_async_filevault.py to import from filevault module
- Fix test_screenshot.py defaults (enabled=True, 1024x768)
- Add backward compatibility exports to filevault.py
- All 196 tests passing
2025-12-31 16:03:43 -05:00
da538ea9b0 README: clarify domain_vault vs filevault, add linkpeek path mapping 2025-12-31 15:46:37 -05:00
99c836e2c8 Unify filevault: merge storage.py into single sync+async module
- filevault.py: Vault (sync) + AsyncVault (async) in one file
- Delete storage.py (redundant async wrapper)
- Both classes share identical API: store, get, exists, delete, stats
- Add content_hash() and hash_to_path() utility functions
- Update all imports: neopig.py, serp.py, test files
- Update README with unified documentation
- 72 lines saved, cleaner architecture
2025-12-31 15:44:39 -05:00
b0542fccc6 Improve depth CLI help and add max depth validation
- Clarify depth help: 0=single page, 1=page+links, -1=unlimited
- Reject depth >18, suggest using -1 for unlimited crawling
- Update CLAUDE.md with depth documentation
2025-12-31 15:37:18 -05:00
8d669e206c Comprehensive README rewrite with full API documentation
- README.md: Complete rewrite in About page style with origin story
- Documents all storage systems: filevault, ImageVault, domain_vault
- Full database schema and method reference
- Screenshot capture with all engines and config options
- HTML to Markdown converter with content detection
- CLI reference for neopig.py, archive.py, serp.py
- All API endpoints documented
2025-12-31 15:21:55 -05:00
0fc1d45ad1 Update crawl UI, job tracking, cancellation, and uncloseai prompt
- Default to 'all' mode on crawl page
- Add Fresh/Fast/Screenshots checkboxes
- Show job types (crawl vs backfill) with distinct labels
- Add Search/Live links per job for domain filtering
- Add Stop button to cancel running crawls
- Track active tasks for cancellation on shutdown
- Fix duplicate job creation (pass job_id to pig.crawl)
- Adaptive polling (3s running, 10s idle)
- Remove page column height constraints on search
- Update uncloseai prompt to use machine learning persona
2025-12-31 12:39:31 -05:00
2c63076d0d Fix None comparison in markdown backfill progress tracking 2025-12-30 16:21:53 -05:00
7daae6c0dc Fix UNIQUE constraint error when pages have identical screenshots 2025-12-30 16:20:15 -05:00
3fa3c9722b Screenshot backfill: query content_length for dynamic delay 2025-12-30 16:17:44 -05:00
5228f21675 Add About page with neopig history and pig.py origin story 2025-12-30 16:13:36 -05:00
c3e8fb564a Screenshots: full_page=True by default, fix backfill success detection, add About nav link 2025-12-30 16:12:21 -05:00
3481fd3098 Screenshot backfill: process ALL pages in DB, not just crawled domain 2025-12-30 16:07:12 -05:00
482d559f00 Screenshot backfill: DB-backed progress tracking like markdown ETL 2025-12-30 15:33:17 -05:00
ad05d1a308 Screenshot backfill: 1x CPU workers in normal mode (not just 1) 2025-12-30 15:31:17 -05:00
cd56e23a75 Screenshot backfill: 3x CPU workers in fast mode 2025-12-30 15:30:25 -05:00
f4996f9c71 Parallel screenshot backfill with --fast mode (2x CPU workers) 2025-12-30 15:29:48 -05:00
9054c45ac8 Fix Uri.host -> Uri.hostname 2025-12-30 15:27:15 -05:00
deaf796ce1 Auto-backfill missing screenshots after crawl completes 2025-12-30 15:26:10 -05:00
16f869d7de Enable screenshots by default, --no-screenshot to disable 2025-12-30 15:21:41 -05:00
905760bb7e Rewrite internal page links to archived versions
- Add lookup_pages_by_uris() for batch page hash lookup
- Rewrite internal links (same domain) to /page/{uri_hash}
- Links to archived pages now stay within neopig
2025-12-30 15:17:34 -05:00
feb6eed596 Fix crawl UI: async task, real-time progress, better defaults
- Fix asyncio error: use create_task() directly instead of BackgroundTasks
- Default depth=9, max_pages=-1 for full site crawls
- Add update_crawl_job_stats() for live progress updates
- Poll jobs every 2s while running, show live stats
- Animated progress bar for running jobs
- Fix get_media_type_from_extension() None path crash
2025-12-30 15:14:49 -05:00
cbed6d9d9a Speed up html2md: lxml parser, combined selectors, content hint
- Use lxml parser (2-5x faster than html.parser), fallback to html.parser
- Combine 20+ noise selectors into single query (1 DOM traversal vs 20)
- Add hint parameter to skip content detection for known types
- Added lxml to requirements.txt
2025-12-30 14:49:04 -05:00
ee9c3cfc74 ETL backfill with jobs table, background flusher, smooth progress
- backfill_jobs table tracks ETL progress with atomic increments
- Background flusher thread syncs progress every 50ms (workers never block)
- Thread-local DB connections for page writes (WAL mode)
- tqdm smoothing=0.1 for stable rate display (30-40 pages/sec)
- 4 processes x 6 threads = 24 workers burning all CPUs
- Zero lost counts - final flush verified against return values
2025-12-30 14:43:25 -05:00
78ec0230b8 Fix progress bar to show 100% at completion 2025-12-30 14:23:07 -05:00
1346590d39 ETL-style parallel markdown backfill with real-time progress
- ProcessPoolExecutor: 1 process per CPU core (bypasses GIL)
- ThreadPoolExecutor: 6 threads per process for I/O throughput
- Thread-local SQLite connections with WAL mode
- Manager().Value() for cross-process progress counter
- Real-time tqdm updates polling shared counter every 50ms
- ~19 pages/sec on 4-core system (4887 pages in 2 min)
2025-12-30 14:22:29 -05:00
293ed64a3b modified: .gitignore
modified:   database.py
	modified:   html2md.py
	modified:   neopig.py
	modified:   screenshot.py
	modified:   serp.py
2025-12-30 11:35:25 -05:00
3952978ba4 Screenshot backfill improvements and oversized image handling
- Filter completed URIs at query level for faster backfill resume
- Split oversized screenshots (>65000px) into multiple JPEG chunks
- Progress bar shows total including skipped, advances on errors
- Suppress PIL DecompressionBombWarning for large screenshots
- Cleaner error logging (truncate verbose wkhtmltoimage output)
- Per-page capture logs moved to debug level
2025-12-30 11:05:10 -05:00
7b4c8b0241 modified: .gitignore
modified:   archive.py
	modified:   html2md.py
	modified:   neopig.py
	modified:   screenshot.py
2025-12-30 09:50:54 -05:00
623213f5b6 Self-extracting archives now use bundled neopig/serp.py
- Removed embedded serve.py (872 lines) from archive.py
- bootstrap.c extracts neopig/*.py to /tmp and runs serp.py
- serp.py: tarball mode serves media directly from tar.gz
- OffsetFile wrapper for reading .run files at correct offset
- ArchiveDB: simple SQLite wrapper for archive search (no async deps)
- Archives bundle all neopig source files for self-contained operation
- --upgrade-neopig flag with progress logging
2025-12-30 07:46:59 -05:00
416b3cb760 Add self-extracting archives with bundled neopig
- Bootstrap C program extracts serve.py and runs from tarball
- Archives now include neopig source files for self-contained crawling
- --upgrade-neopig flag to update neopig in existing archives
- html2md.py: smart HTML-to-markdown converter for forums/blogs/Q&A
- Fix vault path defaults (data/vault instead of vault)
- Streaming tar.gz creation without temp copies
- URL rewriting for local media references in archives
2025-12-30 06:55:20 -05:00
a1a58fbb50 Add backfill-markdown, download button, fix image hydration
- backfill-markdown: regenerate markdown with absolute URLs for a domain
- Download button on /view page with slugified filename from alt/title
- html2text baseurl resolves relative URLs during crawl
- Fallback URL lookup by filename for older crawls
- Video hover-to-play on all video elements
- Avatar CSS float:left for text wrapping
- FileResponse inline disposition (view not download)
- Dynamic screenshot delay based on content length
2025-12-29 15:05:39 -05:00
222c23bb14 modified: CLAUDE.md
modified:   archive.py
	modified:   database.py
	modified:   neopig.py
	modified:   screenshot.py
	modified:   serp.py
2025-12-29 12:13:33 -05:00
36edc3b8dc modified: archive.py
modified:   tests/unit/test_screenshot.py
2025-12-29 11:35:14 -05:00
21e344f675 Add archive.py with --serve flag for live crawl watching
- archive.py: New site archiver wrapper with embedded serve.py
- --serve flag starts SERP server alongside crawl for live viewing
- --fast mode for sites without robots.txt (no crawl delay)
- Symlink-based storage: domain views link to hash vault
- Tarball resolves symlinks to include only domain content
- Fixed bytes_downloaded/bytes_stored accounting for screenshots
- Data directory (data/) for databases and state files
- Standardized on - separator in filenames
2025-12-29 11:26:02 -05:00
444317a71b modified: async_web_fetcher.py
modified:   database.py
	modified:   neopig.py
2025-12-29 05:08:31 -05:00
a3c4c19e54 Fix CI to install from requirements.txt 2025-12-22 20:44:18 -05:00
1847a2fee6 Add comprehensive unit tests for async modules
Tests for:
- async_web_fetcher: URL handling, media extraction, crawl modes, scoring
- domain_vault: VaultManager, HTML/Media/Linkpeek vaults
- screenshot: ScreenshotCapture configuration and availability
- storage: ImageVault with MD5 deduplication

185 tests total, all passing.
2025-12-22 20:40:58 -05:00
54087c5bb8 Fix CI: use python3 instead of python 2025-12-22 20:24:28 -05:00