VibeDialer supports multiple storage backends for saving dial results automatically.
CSV storage saves results to a comma-separated values file, which can be opened in Excel, Google Sheets, or any text editor.
Usage:
# Launch TUI (default) - storage can be configured in interface
vibedialer
# Or use dial command with custom storage
vibedialer dial 555-12 --storage csv --output results.csvFeatures:
- Automatic header row creation
- Append mode - subsequent runs add to existing file
- Human-readable format
- Easy to import into spreadsheet applications
CSV Format:
phone_number,status,timestamp,success,message,carrier_detected,tone_type
555-1234,modem,2025-11-15T12:00:00,True,Modem carrier detected,True,modem
555-1235,busy,2025-11-15T12:01:00,False,Busy signal detected,False,
555-1236,no_answer,2025-11-15T12:02:00,False,No answer after 3 rings,False,SQLite storage saves results to a relational database file, enabling complex queries and analysis.
Usage:
# Default SQLite storage (vibedialer_results.db)
vibedialer dial 555-12 --storage sqlite
# Custom database file
vibedialer dial 555-12 --storage sqlite --output my_results.dbFeatures:
- Indexed for fast queries
- Supports complex SQL queries
- Compact storage format
- Transaction-based for data integrity
Database Schema:
CREATE TABLE dial_results (
id INTEGER PRIMARY KEY AUTOINCREMENT,
phone_number TEXT NOT NULL,
status TEXT NOT NULL,
timestamp TEXT NOT NULL,
success BOOLEAN NOT NULL,
message TEXT,
carrier_detected BOOLEAN,
tone_type TEXT
);
-- Indexes
CREATE INDEX idx_phone_number ON dial_results(phone_number);
CREATE INDEX idx_timestamp ON dial_results(timestamp);
CREATE INDEX idx_status ON dial_results(status);Query Examples:
-- Find all modems detected
SELECT * FROM dial_results WHERE status = 'modem';
-- Count results by status
SELECT status, COUNT(*) as count
FROM dial_results
GROUP BY status
ORDER BY count DESC;
-- Find all results in a date range
SELECT * FROM dial_results
WHERE timestamp BETWEEN '2025-11-15 00:00:00' AND '2025-11-15 23:59:59';Dry-run mode doesn't save any results to disk. Useful for testing or when you don't want to persist data.
Usage:
# Dry-run mode - no data saved
vibedialer dial 555-12 --storage dry-runFeatures:
- No files created
- Results still displayed in TUI
- Logs what would have been saved
- Useful for testing and demonstrations
# CSV storage (default)
vibedialer dial 555-12
# Explicit CSV with custom file
vibedialer dial 555-12 --storage csv --output my_scan.csv
# SQLite storage
vibedialer dial 555-12 --storage sqlite --output scan_results.db
# Dry-run mode
vibedialer dial 555-12 --storage dry-run# Modem backend with CSV storage
vibedialer dial 555-12 --backend modem --storage csv --output modem_scan.csv
# Simulation with SQLite
vibedialer dial 555-12 --backend simulation --storage sqlite --output test.dbWhen using the interactive TUI, storage is configured via CLI flags when launching:
# Launch TUI with CSV storage
vibedialer dial 555-12 --interactive --storage csv --output session.csv
# Launch TUI with SQLite storage
vibedialer dial 555-12 --interactive --storage sqlite --output session.dbThe TUI will automatically save results as you dial.
Results are automatically saved in real-time:
- CSV: Each result is written immediately and flushed to disk
- SQLite: Each result is inserted immediately (transactions auto-committed)
- Dry-Run: Results logged but not persisted
VibeDialer ensures data is saved even when the application exits unexpectedly:
- Normal Exit: Storage is properly closed, all data flushed
- Ctrl+C (SIGINT): Exit handlers ensure data is saved before termination
- Error/Exception: try-finally blocks guarantee cleanup
- TUI Close: on_unmount event triggers storage cleanup
from vibedialer.dialer import PhoneDialer
from vibedialer.backends import BackendType
from vibedialer.storage import StorageType
# Create dialer with CSV storage
dialer = PhoneDialer(
backend_type=BackendType.SIMULATION,
storage_type=StorageType.CSV,
filename="my_results.csv"
)
try:
# Dial numbers - results saved automatically
result = dialer.dial("555-1234")
print(f"Result: {result.status}")
finally:
# Ensure cleanup happens
dialer.cleanup()By default, storage files are created in the current working directory:
- CSV:
vibedialer_results.csv - SQLite:
vibedialer_results.db
Use the --output flag to specify custom locations:
# Absolute path
vibedialer dial 555-12 --storage csv --output /path/to/results.csv
# Relative path
vibedialer dial 555-12 --storage sqlite --output ../data/scan.db- Pros: Human-readable, universally compatible, simple format
- Cons: Slower for large datasets, no query capabilities
Best for: Small to medium scans (< 10,000 numbers), when you need to view results in a spreadsheet
- Pros: Fast queries, indexed, compact, supports complex analysis
- Cons: Binary format (not human-readable without tools)
Best for: Large scans (> 10,000 numbers), when you need to query and analyze results
- Pros: No disk I/O, fastest option
- Cons: Data not persisted
Best for: Testing, demonstrations, when results aren't needed
-
Choose the right storage type:
- CSV for simple scans and manual review
- SQLite for large scans and analysis
- Dry-run for testing
-
Use meaningful filenames:
vibedialer dial 555-12 --storage csv --output scan_555-12_2025-11-15.csv
-
Back up your data:
- Storage files contain valuable scan results
- Consider backing up before re-running scans
-
Clean up old results:
- CSV and SQLite files persist between runs
- Delete old files or use unique names for each scan
Error: [Errno 13] Permission denied: 'results.csv'
Solution: Check file permissions or use a different output location
Error: database is locked
Solution: Close other applications accessing the database file
For large scans, ensure adequate disk space:
- CSV: ~100 bytes per result
- SQLite: ~50 bytes per result (more compact)
VibeDialer can resume from interrupted dialing sessions, picking up where you left off.
# Resume from a CSV file with explicit prefix
vibedialer dial 555-12 --resume vibedialer_results.csv --resume-prefix 555-12
# Resume from SQLite database
vibedialer dial 555-12 --resume vibedialer_results.db --resume-prefix 555-12VibeDialer can automatically infer the pattern from your results file:
# Infer pattern automatically (silent mode)
vibedialer dial 555-12 --resume vibedialer_results.csv
# Infer with confirmation prompt
vibedialer dial 555-12 --resume vibedialer_results.csv --infer-prefixWhen using --infer-prefix, you'll see:
Inferred pattern from vibedialer_results.csv: 555-12
Total numbers in pattern: 100
Already dialed: 37
Remaining to dial: 63
Continue with this pattern? [y/N]:
- Reads Completed Numbers: Scans the results file for already-dialed numbers
- Infers Pattern: Finds the common prefix (e.g., "555-12" from "555-1200", "555-1201", etc.)
- Calculates Remaining: Generates full list and filters out completed numbers
- Continues Dialing: Dials only the remaining numbers
Scenario 1: Power Outage
# Start scan
vibedialer dial 555-12 --backend modem --storage csv
# Power goes out after 37 numbers...
# Resume later
vibedialer dial dummy --resume vibedialer_results.csv --backend modemScenario 2: Network Error
# Scan interrupted at number 523
vibedialer dial 212-555 --backend modem --storage sqlite --output scan.db
# Resume with explicit prefix
vibedialer dial dummy --resume scan.db --resume-prefix 212-555 --backend modemScenario 3: Partial Completion
# You dialed 555-1200 through 555-1250, want to finish 555-12xx
# Check what's left with --infer-prefix
vibedialer dial dummy --resume results.csv --infer-prefix
# If pattern looks good, resume
vibedialer dial dummy --resume results.csv --backend modemYou can resume from one file and save to another:
# Resume from CSV, save to SQLite
vibedialer dial dummy \
--resume old_scan.csv \
--storage sqlite \
--output new_scan.db
# Resume from SQLite, save to new CSV
vibedialer dial dummy \
--resume scan.db \
--storage csv \
--output continued_scan.csv| Flag | Description |
|---|---|
--resume <file> |
Resume from results file (CSV or SQLite) |
--resume-prefix <prefix> |
Explicit pattern to resume (e.g., "555-12") |
--infer-prefix |
Show inferred pattern and ask for confirmation |
VibeDialer infers patterns by finding the common prefix of dialed numbers:
555-1200through555-1299→555-12(100 numbers)555-0000through555-9999→555(10,000 numbers)212-5550through212-5559→212-555(10 numbers)
For best results:
- Keep prefix explicit when resuming large ranges
- Use
--infer-prefixto verify pattern before long scans - Resume files should contain contiguous ranges for accurate inference
"Could not infer pattern"
- Solution: Use
--resume-prefixto specify pattern explicitly - Cause: Numbers in file don't share a common prefix
"No dialed numbers found"
- Solution: Check file path and format
- Cause: Empty results file or wrong file type
Wrong pattern inferred
- Solution: Use
--infer-prefixto check, then provide explicit--resume-prefix - Cause: Mixed patterns in same file
# Connect to database
sqlite3 vibedialer_results.db
# Example queries
.mode column
.headers on
SELECT status, COUNT(*) FROM dial_results GROUP BY status;
SELECT * FROM dial_results WHERE carrier_detected = 1;# Import CSV into SQLite
sqlite3 results.db <<EOF
.mode csv
.import vibedialer_results.csv dial_results
EOFsqlite3 -header -csv vibedialer_results.db \
"SELECT * FROM dial_results" > export.csv