Commit graph

23 commits

Author SHA1 Message Date
d7f736f5ab Fix replay: stream immediately with pagination, skip poll() in replay mode 2026-01-04 11:04:00 -05:00
e5972a3171 Add instant replay for crawl jobs and NEOPIG_NO_VCS flag
- Add /api/crawl/jobs/{job_id}/replay SSE endpoint for replaying crawls
- Replay streams media at original discovery pace with speed multiplier
- Add Replay button to crawl jobs UI (works even when crawling disabled)
- Track active replays to prevent double-clicking same job
- Live feed page handles ?replay=JOB_ID parameter for replay mode
- Add NEOPIG_NO_VCS=1 env var to skip VCS repository detection
- Fix hljs.highlightAll() call when highlight.js not loaded
2026-01-04 10:47:11 -05:00
39218893bf Show original filename under media thumbnails
- database.py: Add media_uri to get_page_media and search queries
- View gallery: Show filename under each thumbnail
- Search results: Show filename above hash
- Live feed: Show filename as card title
2026-01-02 15:48:24 -05:00
0696e92ae3 Add VCS repo cloning support (git/hg/svn/fossil)
Smart source detection: like Hydra for RSS feeds, auto-detect
repository URLs and clone instead of HTTP crawling.

- repo.py: detect_vcs(), clone_repo(), walk_files(), symlink_to_vault()
- Symlink storage: files in repo_vault/ symlink to content-addressed vault/
- Database: repo_uri, repo_path, commit_hash, vcs_type columns
- Auto-detect GitHub, GitLab, Bitbucket, sr.ht, hg.mozilla.org, etc.
2026-01-02 14:37:53 -05:00
e2a556f7a4 Add error column to CrawlJob and make import resilient to missing tables 2026-01-02 12:43:16 -05:00
59f05245d9 Fix database method names for import job status updates 2026-01-02 12:35:24 -05:00
59e7ad5669 Add job purge: delete all traces of a crawl job
Order of operations (critical for data integrity):
1. Get job info and collect hashes/URIs to delete
2. Delete MediaSource records (breaks references)
3. Delete Page records
4. Delete orphan Media records (not referenced by other jobs)
5. Delete orphan media files from vault
6. Delete screenshot files for deleted pages
7. Delete CrawlJob record
8. Delete state files

CLI: python neopig.py --purge-job JOB_ID
API: DELETE /api/crawl/jobs/{job_id}?purge=true (default)
UI: Delete button now purges by default
2026-01-01 16:47:59 -05:00
e61b9cfd04 Track media first_seen_at and last_seen_at timestamps
- Add last_seen_at column to Media table (updated on every encounter)
- first_seen_at tracks initial discovery
- last_seen_at tracks most recent sighting
- MediaSource.discovered_at already tracks per-page first link time
- Enables tracking media reuse across the web
2026-01-01 16:41:52 -05:00
17efcf9a27 Archive improvements: venv support, package-only mode, resume fixes
- bootstrap.c: Extract requirements.txt, create venv, pip install deps
- archive.py: Add --package-only flag, use neopig vault directly
- archive.py: Resume now loads crawled pages from DB
- database.py: Add close() and get_crawled_page_uris()
- domain_vault.py: Fix None path handling in url_to_filepath
- Makefile: Add test-alpha target for testing archives
2026-01-01 15:57:23 -05:00
750b6ee07c Fix crawl job resume settings + progress bar shows actual %
- Store depth, max_pages, fast, screenshots in crawl_jobs table
- Resume uses stored settings instead of hardcoded defaults
- Progress bar shows pages_crawled / total instead of animation
2026-01-01 09:09:03 -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
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
deaf796ce1 Auto-backfill missing screenshots after crawl completes 2025-12-30 15:26:10 -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
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
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
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
444317a71b modified: async_web_fetcher.py
modified:   database.py
	modified:   neopig.py
2025-12-29 05:08:31 -05:00
6dab26d6fa Initial neopig: async media crawler with MD5 deduplication
- Multi-target concurrent crawling support
- Content-addressable vault storage (MD5 hash)
- SQLite database with page context for searchability
- Live SERP with real-time polling feed (/live)
- URI naming convention (media_uri, page_uri)
- GIF and image object-fit: contain for proper display
2025-12-21 17:26:42 -05:00