Skip to content

Verify and confirm Git setup for main branch#33

Merged
digitalstore2025 merged 4 commits intomainfrom
copilot/setup-git-and-push-main-branch
Apr 20, 2026
Merged

Verify and confirm Git setup for main branch#33
digitalstore2025 merged 4 commits intomainfrom
copilot/setup-git-and-push-main-branch

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 15, 2026

The issue requested initializing Git, committing all files, and pushing the main branch to the remote origin.

Findings

The repository was already fully configured — no changes were required:

  • Git initialized with a clean working tree
  • .gitignore correctly excludes node_modules, dist, .env*, and build artifacts
  • .env.example present with placeholders for GEMINI_API_KEY and other secrets
  • package.json defines all dependencies (react, react-dom, @google/genai) and dev tooling (vite, typescript, @vitejs/plugin-react)
  • Remote origin configured and branch pushed to github.com/digitalstore2025/-

All steps from the issue were satisfied by the existing repository state.

Summary by Sourcery

Improve podcast episode rendering, harden error handling in the generation API, and update setup checks for the RSS parsing dependency.

Bug Fixes:

  • Fix podcast episode audio URLs to safely handle episode names via URL encoding.
  • Return a generic 500 error message for generation failures while logging full exception details server-side.

Enhancements:

  • Render podcast episodes via DOM construction instead of injecting raw HTML to make the UI more robust.

Build:

  • Update setup script dependency check from feedparser to atoma.

Copilot AI linked an issue Apr 15, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Set up Git and push main branch Verify and confirm Git setup for main branch Apr 15, 2026
Copilot AI requested a review from digitalstore2025 April 15, 2026 08:57
@digitalstore2025 digitalstore2025 changed the base branch from main to claude/ai-palestinian-broadcast-56tZN April 15, 2026 11:08
@digitalstore2025 digitalstore2025 changed the base branch from claude/ai-palestinian-broadcast-56tZN to chore/deploy-ready-vite April 15, 2026 15:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR substantially expands the repository by adding a new broadcast-ai/ Python subsystem for generating and serving broadcast-style Arabic audio/video (TV loop, radio, podcasts, scheduling, RSS integration), plus setup/bootstrap scripts and a new GitHub Actions workflow. This scope does not match the PR title/description, which describe only verifying Git setup for main.

Changes:

  • Add a full Flask-based web UI + REST API for streaming, schedules, history, episodes, and on-demand TTS generation.
  • Add broadcast generation pipelines (TV loop w/ optional Wav2Lip, radio mode, podcast generation, voiceover batch generation) with shared config/logging/RSS/scheduler utilities.
  • Add setup/bootstrap scripts, dependency updates, repo ignore changes, and replace the GitHub workflow.

Reviewed changes

Copilot reviewed 23 out of 24 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
broadcast-ai/voiceover.py Adds voiceover generation utilities (single + batch) with optional ffmpeg padding.
broadcast-ai/tv_server.py Replaces minimal streaming server with a full web UI + REST API endpoints.
broadcast-ai/train.py Enhances training pipeline with dataset validation, CLI flags, and logging.
broadcast-ai/setup_wav2lip.sh Adds automated Wav2Lip installation + model download verification.
broadcast-ai/setup.sh Expands setup steps, verifies imports, creates directories, and documents quick start.
broadcast-ai/scheduler.py Introduces time-based scheduling for broadcast content blocks.
broadcast-ai/run_tv_channel.py Upgrades TV loop to schedule-aware generation with RSS and segment history.
broadcast-ai/rss_feed.py Adds RSS fetching + caching + “unseen headlines” logic (atoma/stdlib fallback).
broadcast-ai/requirements.txt Updates Python dependencies (adds atoma, imageio-ffmpeg; removes feedparser).
broadcast-ai/radio_station.py Adds audio-only radio broadcast loop with optional bumper generation.
broadcast-ai/podcast_generator.py Adds podcast episode generation and WAV concatenation via ffmpeg.
broadcast-ai/main.py Adds unified launcher to run TV/radio/server/podcast/voiceover modes.
broadcast-ai/logger.py Adds shared console+file logging helper.
broadcast-ai/generate.py Adds style-based generation, caching, validation, retry logic, lazy TTS import.
broadcast-ai/download_quran_dataset.py Adds Quran dataset downloader + metadata builder.
broadcast-ai/demo.py Adds demo mode that runs without fine-tuning by using pre-trained XTTS v2.
broadcast-ai/config.py Centralizes paths, audio params, schedules, RSS feeds, and content pools.
broadcast-ai/bootstrap.sh Adds “one-command” bootstrap flow to install deps and launch demo.
broadcast-ai/README.md Removes the previous broadcast-ai README (documentation removed).
broadcast-ai/.gitignore Extends ignores for generated output, logs, and cache under broadcast-ai/.
.gitignore Simplifies root ignore list and adds env/coverage/log ignores.
.github/workflows/jekyll-docker.yml Removes the Jekyll CI workflow.
.github/workflows/build.yml Adds a Node “Build and Test” workflow (currently build-only).
.env.example Adds an example env file with placeholder secret keys/URLs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread broadcast-ai/voiceover.py
Comment thread broadcast-ai/generate.py
Comment thread broadcast-ai/generate.py
Comment thread broadcast-ai/generate.py
Comment thread broadcast-ai/tv_server.py Outdated
Comment thread broadcast-ai/train.py
Comment thread broadcast-ai/radio_station.py
Comment thread broadcast-ai/tv_server.py
Comment thread broadcast-ai/tv_server.py Outdated
Comment thread .github/workflows/build.yml
digitalstore2025 and others added 3 commits April 17, 2026 02:48
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@digitalstore2025 digitalstore2025 marked this pull request as ready for review April 20, 2026 16:16
@digitalstore2025 digitalstore2025 changed the base branch from chore/deploy-ready-vite to main April 20, 2026 16:16
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 20, 2026

Reviewer's Guide

Refines the broadcast AI dashboard’s podcast rendering to be DOM-based and URL-safe, hardens the TTS generation API error handling with logging, and updates the setup script to validate the new RSS dependency (atoma instead of feedparser).

Sequence diagram for hardened TTS generation API error handling

sequenceDiagram
    participant Client
    participant FlaskApp
    participant tv_server_api_generate
    participant TTSGenerator as generate_voice
    participant Logger as log

    Client->>FlaskApp: POST /api/generate (text, style, output_name)
    FlaskApp->>tv_server_api_generate: Call api_generate
    tv_server_api_generate->>tv_server_api_generate: t0 = time.time()
    tv_server_api_generate->>TTSGenerator: generate_voice(text, style, output_name)
    alt Generation succeeds
        TTSGenerator-->>tv_server_api_generate: path
        tv_server_api_generate->>tv_server_api_generate: duration = round(time.time() - t0, 1)
        tv_server_api_generate-->>FlaskApp: jsonify({path, duration, style})
        FlaskApp-->>Client: 200 OK JSON
    else Unhandled exception
        TTSGenerator-->>tv_server_api_generate: Exception
        tv_server_api_generate->>Logger: log.exception("Unhandled error during /api/generate request")
        tv_server_api_generate-->>FlaskApp: jsonify({error: "Internal server error"}), 500
        FlaskApp-->>Client: 500 JSON {error: Internal server error}
    end
Loading

Flow diagram for DOM-based podcast episodes rendering

flowchart TD
    A["Fetch /api/episodes"] --> B{Response OK?}
    B -- No --> C["Set episodes.innerHTML to خطأ في التحميل"]
    B -- Yes --> D{episodes list empty?}
    D -- Yes --> E["Set episodes.innerHTML to لا توجد حلقات بعد. شغّل podcast_generator.py لإنشاء حلقات."]
    D -- No --> F["Clear container with episodes.replaceChildren()"]
    F --> G["For each episode ep with index i"]
    G --> H["Create item div and style margins, padding, border"]
    H --> I["Create strong title with text حلقـة (i+1)"]
    I --> J["Append separator text node —"]
    J --> K["Create span name with class status and text ep.name"]
    K --> L["Create audio element with controls, width 100%, marginTop 0.5rem"]
    L --> M["Create source element"]
    M --> N["Set source.src to /api/episode/ + encodeURIComponent(ep.name)"]
    N --> O["Set source.type to audio/wav"]
    O --> P["Append source to audio"]
    P --> Q["Append audio to item"]
    Q --> R["Append item to episodes container"]
Loading

File-Level Changes

Change Details Files
Refactor podcast episodes rendering on the TV server dashboard to build DOM nodes directly and safely encode episode URLs.
  • Replace string concatenation of HTML for podcast episodes with imperative DOM element creation for each episode item.
  • Use replaceChildren() to clear the episodes container before repopulating it.
  • Ensure episode URLs are generated with encodeURIComponent to safely handle arbitrary episode names.
  • Preserve styling and structure (title, status span, audio player, and source) via explicit element attributes and properties.
broadcast-ai/tv_server.py
Strengthen error handling for the TTS generation API endpoint by logging unexpected exceptions and returning a generic 500 response.
  • Wrap the TTS generation logic in a try/except that logs exceptions via log.exception for /api/generate requests.
  • Change the error payload returned on exception to a generic 'Internal server error' to avoid leaking internal details while still using HTTP 500 status.
broadcast-ai/tv_server.py
Update setup diagnostics to check for the atoma RSS library instead of feedparser.
  • Modify the setup script’s dependency verification step to import atoma and print a success or failure message accordingly, aligning with the updated RSS tooling stack.
broadcast-ai/setup.sh

Assessment against linked issues

Issue Objective Addressed Explanation
#30 Have the project tracked in Git with an initialized repository, all current files committed, and a clean working tree on the main branch.
#30 Configure the remote origin for the repository and ensure the local main branch is pushed to the remote with upstream tracking set.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The /api/generate error response has changed from returning the actual exception message to a generic "Internal server error" string; if any existing client logic relies on the previous error text, consider preserving it in a separate field (e.g. detail) or gating the new behavior behind a flag.
  • In the podcasts_page script, you now use replaceChildren() and explicit DOM creation for the success path but still set innerHTML directly in the .catch handler; for consistency and to avoid potential HTML injection, consider updating the error path to also construct DOM nodes programmatically.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `/api/generate` error response has changed from returning the actual exception message to a generic "Internal server error" string; if any existing client logic relies on the previous error text, consider preserving it in a separate field (e.g. `detail`) or gating the new behavior behind a flag.
- In the `podcasts_page` script, you now use `replaceChildren()` and explicit DOM creation for the success path but still set `innerHTML` directly in the `.catch` handler; for consistency and to avoid potential HTML injection, consider updating the error path to also construct DOM nodes programmatically.

## Individual Comments

### Comment 1
<location path="broadcast-ai/tv_server.py" line_range="435-437" />
<code_context>
         return jsonify({"path": path, "duration": duration, "style": style})
-    except Exception as exc:
-        return jsonify({"error": str(exc)}), 500
+    except Exception:
+        log.exception("Unhandled error during /api/generate request")
+        return jsonify({"error": "Internal server error"}), 500


</code_context>
<issue_to_address>
**suggestion:** The generic error response might make client-side debugging harder without an error identifier.

While the generic message improves security, it makes it harder for clients to correlate failures with server logs. Consider including an opaque error ID in the JSON response (e.g. `{"error": "Internal server error", "id": trace_id}`) and logging the same ID with the exception to preserve debuggability without exposing implementation details.

Suggested implementation:

```python
    except Exception:
        error_id = str(uuid.uuid4())
        log.exception("Unhandled error during /api/generate request (error_id=%s)", error_id)
        return jsonify({"error": "Internal server error", "id": error_id}), 500

```

Add `import uuid` alongside the other imports at the top of `broadcast-ai/tv_server.py`, for example:

<<<<<<< SEARCH
import time
=======
import time
import uuid
>>>>>>> REPLACE

If the import section differs, adjust the SEARCH block to match an existing nearby import line and insert `import uuid` appropriately.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread broadcast-ai/tv_server.py
@chatgpt-codex-connector
Copy link
Copy Markdown

💡 Codex Review

raw_path = str(config.OUTPUT_DIR / "raw.wav")

P1 Badge Use unique temp WAV path per synthesis call

generate_voice always writes intermediate audio to output/raw.wav, which becomes a shared mutable file across concurrent callers. This commit adds concurrent generation paths (main.py --all runs TV and radio in parallel, and /api/generate can run while broadcasting), so overlapping calls can overwrite each other’s raw audio before post-processing, causing corrupted/mismatched segments or intermittent ffmpeg failures. Use a per-call temp filename (e.g., UUID or tempfile) to isolate synthesis jobs.


ln -sf "$FFMPEG_PATH" /usr/local/bin/ffmpeg 2>/dev/null || true
echo " [OK] ffmpeg installed via imageio-ffmpeg"

P2 Badge Verify ffmpeg availability after fallback install

In quick bootstrap mode without system ffmpeg, the script installs imageio-ffmpeg and then silently ignores symlink failures to /usr/local/bin (|| true) but still prints success. On non-root environments this commonly leaves ffmpeg unavailable on PATH, so later audio/video generation commands fail despite the setup claiming success. Add an explicit command -v ffmpeg check after this block and fail (or export a usable path) when unavailable.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@digitalstore2025 digitalstore2025 merged commit 73eaba9 into main Apr 20, 2026
3 checks passed
@digitalstore2025
Copy link
Copy Markdown
Owner

@copilot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Set up Git and push main branch

3 participants