Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/auto-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Auto PR

on:
push:
branches:
- 'claude/**'

jobs:
create-pr:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Create PR if none exists
env:
GH_TOKEN: ${{ github.token }}
run: |
set -e
BRANCH="${GITHUB_REF_NAME}"

# Check if a PR already exists for this branch
EXISTING=$(gh pr list --head "$BRANCH" --json number --jq length)
if [ "$EXISTING" -gt 0 ]; then
echo "PR already exists for $BRANCH, skipping."
exit 0
fi

# Build title from branch name: claude/some-feature-name-XYZ -> Some feature name
RAW=$(echo "$BRANCH" | sed 's|claude/||' | sed 's|-[A-Za-z0-9]*$||' | tr '-' ' ')
TITLE="$(echo "$RAW" | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1')"

# Get commit messages for the body
COMMITS=$(git log origin/main..HEAD --pretty=format:"- %s" 2>/dev/null || echo "- Initial commit")

# Build body using printf to avoid YAML indentation issues
BODY=$(printf '## Commits\n%s\n\n---\n*Auto-generated PR from branch `%s`*' "$COMMITS" "$BRANCH")

gh pr create \
--title "$TITLE" \
--body "$BODY" \
--base main \
--head "$BRANCH"
10 changes: 8 additions & 2 deletions netlify/functions/scrape.mjs
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
// Reddit scraper serverless function for Netlify
// Uses public JSON endpoints — no API credentials required

const USER_AGENT = "MyBoyfriendIsAI-Scraper/1.0 (research; no auth)";
const USER_AGENT =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
const BASE_URL = "https://www.reddit.com";

async function fetchWithRetry(url, options = {}, retries = 3) {
for (let attempt = 0; attempt < retries; attempt++) {
const resp = await fetch(url, {
...options,
headers: { "User-Agent": USER_AGENT, ...options.headers },
headers: {
"User-Agent": USER_AGENT,
Accept: "application/json, text/html;q=0.9, */*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
...options.headers,
},
});

if (resp.status === 429) {
Expand Down
4 changes: 3 additions & 1 deletion scraper.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
from config import SUBREDDIT, DEFAULT_POST_LIMIT, SORT_MODES

HEADERS = {
"User-Agent": "MyBoyfriendIsAI-Scraper/1.0 (research; no auth)",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"Accept": "application/json, text/html;q=0.9, */*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
}
BASE_URL = "https://www.reddit.com"

Expand Down
16 changes: 16 additions & 0 deletions web/app.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
// Theme toggle
(function initTheme() {
const saved = localStorage.getItem("theme");
if (saved) document.documentElement.setAttribute("data-theme", saved);
document.addEventListener("DOMContentLoaded", () => {
const btn = document.getElementById("themeToggle");
if (!btn) return;
btn.addEventListener("click", () => {
const current = document.documentElement.getAttribute("data-theme");
const next = current === "light" ? "dark" : "light";
document.documentElement.setAttribute("data-theme", next);
localStorage.setItem("theme", next);
});
});
})();

// Default keyword categories (optional — only used when keyword analysis is enabled)
const DEFAULT_KEYWORDS = {
hiding_secrecy: [
Expand Down
1 change: 1 addition & 0 deletions web/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Reddit Scraper</title>
<link rel="icon" type="image/svg+xml" href="favicon.svg">
<link rel="stylesheet" href="style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
Expand All @@ -17,6 +18,10 @@
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M16 8s-1.5-2-4-2-4 2-4 2"/><line x1="9" y1="15" x2="9.01" y2="15"/><line x1="15" y1="15" x2="15.01" y2="15"/></svg>
Reddit Scraper
</div>
<button class="theme-toggle" id="themeToggle" title="Toggle theme">
<svg class="icon-sun" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
<svg class="icon-moon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
</button>
</div>
</nav>

Expand Down
72 changes: 72 additions & 0 deletions web/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ body {
max-width: 720px;
margin: 0 auto;
padding: 0.9rem 1.25rem;
display: flex;
justify-content: space-between;
align-items: center;
}

.logo {
Expand Down Expand Up @@ -657,6 +660,75 @@ footer {
border-top: 1px solid var(--border);
}

/* Theme toggle */
.theme-toggle {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 20px;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
color: var(--text-muted);
transition: all 0.2s;
}

.theme-toggle:hover {
border-color: var(--accent);
color: var(--accent);
background: var(--accent-glow);
}

.theme-toggle .icon-moon { display: none; }
.theme-toggle .icon-sun { display: block; }

[data-theme="light"] .theme-toggle .icon-moon { display: block; }
[data-theme="light"] .theme-toggle .icon-sun { display: none; }

/* Limoncello light theme */
[data-theme="light"] {
--bg: #fefdf6;
--bg-raised: #fdf9e8;
--bg-surface: #f5f0d0;
--bg-hover: #ede8c4;
--border: #ddd6a8;
--border-light: #cec780;
--text: #2d2b1e;
--text-muted: #6b6744;
--text-dim: #9a9470;
--accent: #a89132;
--accent-hover: #bfa42a;
--accent-glow: rgba(168, 145, 50, 0.12);
--accent-glow-strong: rgba(168, 145, 50, 0.22);
--green: #3d8b40;
--green-dim: rgba(61, 139, 64, 0.1);
--red: #c0392b;
--red-dim: rgba(192, 57, 43, 0.08);
--orange: #cc7a00;
}

[data-theme="light"] .topbar {
background: rgba(254, 253, 246, 0.85);
}

[data-theme="light"] .error-card {
color: #c0392b;
}

[data-theme="light"] .toggle-slider::after {
background: #fff;
}

[data-theme="light"] .btn-scrape {
color: #fff;
}

[data-theme="light"] .btn-stop {
color: #fff;
}

/* Hidden */
.hidden { display: none !important; }

Expand Down