From 1bd8545a730e4c3ca7b6cd3bad798b8bdd12f398 Mon Sep 17 00:00:00 2001 From: Alex Adams <70454645+aadams149@users.noreply.github.com> Date: Sat, 28 Feb 2026 18:24:47 -0500 Subject: [PATCH 1/2] Add GitHub Actions CI workflow for linting and testing Runs flake8 and ruff on push/PR, plus pytest when tests/ exists. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/ci.yml | 63 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..37cf953 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,63 @@ +name: CI + +on: + push: + branches: ["*"] + pull_request: + branches: [main] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install linters + run: pip install flake8 ruff + + - name: Run flake8 + run: | + flake8 . \ + --max-line-length=120 \ + --extend-ignore=E501,W503,E402,E722,W291,W293,W391,E303,E302,E305,E261,E262 \ + --exclude=.git,__pycache__,build,dist,.claude,*.egg-info,venv,.venv \ + --count --show-source --statistics + + - name: Run ruff + run: | + ruff check . \ + --line-length=120 \ + --extend-ignore=E501,E402,E722 \ + --extend-exclude=".git,__pycache__,build,dist,.claude,venv,.venv" + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install Tesseract OCR + run: sudo apt-get update && sudo apt-get install -y tesseract-ocr + + - name: Install dependencies + run: | + pip install --upgrade pip + pip install -r requirements.txt + pip install pytest + + - name: Run tests + run: | + if [ -d "tests" ]; then + python -m pytest tests/ -v --tb=short + else + echo "No tests directory found, skipping tests" + fi From e76e976c5c5edde6e3d3a3a2026d7a08ef6ec43d Mon Sep 17 00:00:00 2001 From: Alex Adams <70454645+aadams149@users.noreply.github.com> Date: Sat, 28 Feb 2026 22:55:17 -0500 Subject: [PATCH 2/2] Fix lint errors and tune CI ignore list Remove f-prefix from strings without placeholders (F541), unused variable bg_color (F841), missing newline at EOF (W292). Broaden flake8/ruff ignore list for pre-existing style issues (F401, E127, E128, E221) and exclude legacy copy file. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/ci.yml | 8 ++++---- dashboard/journal_chat.py | 4 ++-- dashboard/journal_dashboard.py | 2 +- ocr/auto_ocr_watcher.py | 6 +++--- plugins/calendar_view.py | 1 - rag/journal_rag.py | 8 ++++---- 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37cf953..d327515 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,16 +24,16 @@ jobs: run: | flake8 . \ --max-line-length=120 \ - --extend-ignore=E501,W503,E402,E722,W291,W293,W391,E303,E302,E305,E261,E262 \ - --exclude=.git,__pycache__,build,dist,.claude,*.egg-info,venv,.venv \ + --extend-ignore=E501,W503,E402,E722,W291,W293,W391,E303,E302,E305,E261,E262,E127,E128,E221,F401,F403 \ + --exclude=".git,__pycache__,build,dist,.claude,*.egg-info,venv,.venv,dashboard/journal_dashboard - Copy.py" \ --count --show-source --statistics - name: Run ruff run: | ruff check . \ --line-length=120 \ - --extend-ignore=E501,E402,E722 \ - --extend-exclude=".git,__pycache__,build,dist,.claude,venv,.venv" + --extend-ignore=E501,E402,E722,F401,F403 \ + --extend-exclude=".git,__pycache__,build,dist,.claude,venv,.venv,dashboard/journal_dashboard - Copy.py" test: runs-on: ubuntu-latest diff --git a/dashboard/journal_chat.py b/dashboard/journal_chat.py index 871b56f..dd48318 100644 --- a/dashboard/journal_chat.py +++ b/dashboard/journal_chat.py @@ -193,9 +193,9 @@ st.sidebar.metric("Total Entries", stats['total_entries']) st.sidebar.metric("Total Words", f"{stats['total_words']:,}") if stats['date_range']['first']: - st.sidebar.text(f"Date Range:") + st.sidebar.text("Date Range:") st.sidebar.text(f"{stats['date_range']['first']}") - st.sidebar.text(f"to") + st.sidebar.text("to") st.sidebar.text(f"{stats['date_range']['last']}") except Exception: pass diff --git a/dashboard/journal_dashboard.py b/dashboard/journal_dashboard.py index 0b9af4f..7de5906 100644 --- a/dashboard/journal_dashboard.py +++ b/dashboard/journal_dashboard.py @@ -949,4 +949,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/ocr/auto_ocr_watcher.py b/ocr/auto_ocr_watcher.py index f0de0fb..524f45c 100644 --- a/ocr/auto_ocr_watcher.py +++ b/ocr/auto_ocr_watcher.py @@ -104,12 +104,12 @@ def watch_folder(watch_dir: str, output_dir: str, engine: str = "tesseract"): if not watch_path.exists(): raise FileNotFoundError(f"Watch directory does not exist: {watch_dir}") - print(f"Starting journal photo watcher...") + print("Starting journal photo watcher...") print(f" Watching: {watch_path.absolute()}") print(f" Output: {output_dir}") print(f" OCR Engine: {engine}") - print(f"\nAdd new journal photos to the watch folder to process them automatically.") - print(f" Press Ctrl+C to stop.\n") + print("\nAdd new journal photos to the watch folder to process them automatically.") + print(" Press Ctrl+C to stop.\n") # Initialize pipeline pipeline = JournalOCRPipeline(engine=engine, output_dir=output_dir) diff --git a/plugins/calendar_view.py b/plugins/calendar_view.py index face6a0..20347c3 100644 --- a/plugins/calendar_view.py +++ b/plugins/calendar_view.py @@ -54,7 +54,6 @@ def render(ctx): theme = ctx.load_theme() link_color = theme.get("link_color", "#0066cc") - bg_color = theme.get("bg_color", "#ffffff") text_color = theme.get("text_color", "#111111") # Determine a subtle highlight for entry days diff --git a/rag/journal_rag.py b/rag/journal_rag.py index d61b5ff..407cd1e 100644 --- a/rag/journal_rag.py +++ b/rag/journal_rag.py @@ -474,7 +474,7 @@ def interactive_search(rag: JournalRAG, use_llm: bool = False, llm_model: str = print("="*60) stats = rag.get_stats() - print(f"\nDatabase Stats:") + print("\nDatabase Stats:") print(f" Entries: {stats['total_entries']}") print(f" Date Range: {stats['date_range']['first']} to {stats['date_range']['last']}") print(f" Total Words: {stats['total_words']:,}") @@ -541,7 +541,7 @@ def interactive_search(rag: JournalRAG, use_llm: bool = False, llm_model: str = elif command == 'list': entries = rag.list_all_entries() - print(f"\nAll entries in database:\n") + print("\nAll entries in database:\n") for entry in entries: print(f" {entry['date']} - {entry['chunks']} chunks, ~{entry['word_count']} words") print() @@ -565,7 +565,7 @@ def interactive_search(rag: JournalRAG, use_llm: bool = False, llm_model: str = elif command == 'stats': stats = rag.get_stats() - print(f"\nDatabase Statistics:") + print("\nDatabase Statistics:") print(f" Total Entries: {stats['total_entries']}") print(f" Total Chunks: {stats['total_chunks']}") print(f" Total Words: {stats['total_words']:,}") @@ -680,7 +680,7 @@ def main(): elif args.command == 'list': entries = rag.list_all_entries() - print(f"\nAll entries in database:\n") + print("\nAll entries in database:\n") for entry in entries: print(f" {entry['date']} - {entry['chunks']} chunks, ~{entry['word_count']} words") print(f"\nTotal: {len(entries)} entries\n")