Skip to content

Latest commit

 

History

History
106 lines (79 loc) · 3.85 KB

File metadata and controls

106 lines (79 loc) · 3.85 KB

Contributing to DarcAds

Thanks for helping out. DarcAds aims to be the tool people reach for instead of paying a subscription, which means it has to stay reliable on machines we will never see.

Setup

git clone https://github.com/<your-username>/DarcAds.git
cd DarcAds
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
pip install -r requirements-optional.txt   # optional, for testing those paths

python3 main.py --doctor                   # confirm ffmpeg is found
python3 -m unittest discover -s tests

The one rule that matters

Every stage must degrade, never fail.

A missing API key, a dead image URL, a provider outage, an ffmpeg build without libass, a product page with no images — none of these may stop a video from being produced. Fall back to the next-best option, log what happened, and keep going.

Concretely, if you add a provider:

  1. Return None on failure rather than raising
  2. warn() with enough detail for the user to fix it
  3. Make sure the caller has a fallback below you
  4. Add a test asserting the fallback fires

The keyless path is what most people run first. If a change makes the free output worse, it is not an improvement.

Where things go

Adding Goes in
A storefront parser src/ingest.py — add a strategy, keep the existing order
A hook framework src/llm_director.pyHOOK_FRAMEWORKS and an offline copy template
A TTS engine src/voice.py — a _tts_* function plus an ENGINE_ORDER entry
A video provider src/visuals.py — a _*_generate function, wired into generate_scene_visual
An avatar provider src/avatars.py
A caption style src/captions.pyrender_caption_frame
A render feature src/compiler.py — prefer a new stage over a bigger filter graph

Shared data structures belong in src/models.py. Anything that reads the environment belongs in src/config.py.

Code style

  • Python 3.9 compatible. Use Optional[X] / List[X], not X | None — the pydantic models are evaluated at runtime and | unions break on 3.9.
  • Type hints on every function.
  • Validate data crossing a module boundary with pydantic.
  • Deterministic and modular. The LLM decides copy; code decides everything else. That is what keeps output debuggable.
  • Comment the why, not the what. A comment explaining why crossfade headroom is added to each clip earns its place; one saying "loop over scenes" does not.
  • Match the surrounding code's naming and density.

Testing

python3 -m unittest discover -s tests
python3 -m unittest tests.test_compiler        # one module
  • No network in tests. Mock requests, and patch src.voice._ENGINES to disable TTS.
  • Test the fallback, not just the happy path — that is where the bugs are.
  • Compiler and pipeline tests run real ffmpeg and take a couple of minutes. Keep new render tests short (1–2 second clips, quality="draft").
  • If you fix a bug, add the test that would have caught it.

Pull requests

  1. Branch from main
  2. Keep it focused — one concern per PR
  3. Run the full suite
  4. If you touched rendering, attach a before/after frame or clip
  5. Describe what a user will notice, not just what changed

Reporting bugs

Include the output of python3 main.py --doctor, your OS and Python version, the exact command, and the product URL if it can be shared. For render issues, the output/*_run.json manifest is the most useful single artefact.

Scope

In scope: better scraping, better copy, better renders, more providers, more platforms, docs.

Out of scope: anything that requires a hosted DarcAds service, telemetry, or that makes an API key mandatory for a stage that currently works without one.

Licence

Contributions are accepted under the MIT licence. Do not commit copyrighted music, fonts you cannot redistribute, or anyone's likeness.