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
197 changes: 197 additions & 0 deletions .github/workflows/ci-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
name: ci-test

on:
pull_request:
push:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

permissions:
contents: read

env:
DEFAULT_PYTHON_VERSION: "3.11"

jobs:
smoke-tests:
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

- name: Run smoke tests
run: pytest -q --maxfail=1 tests/smoke

pre-commit:
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

- name: Run pre-commit
run: pre-commit run --all-files --show-diff-on-failure

lint:
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

- name: Run Ruff format check
run: ruff format --check .

- name: Run Ruff lint
run: ruff check .

- name: Run mypy
run: mypy src/

unit-tests:
needs: [smoke-tests]
runs-on: ubuntu-latest
timeout-minutes: 20

env:
COVERAGE_FILE: coverage-unit.dat

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

- name: Run unit tests
run: pytest -q tests/unit --cov=denbust --cov-report=term-missing --cov-report=

- name: Upload unit coverage data
uses: actions/upload-artifact@v4
with:
name: coverage-unit-data
path: coverage-unit.dat

integration-tests:
needs: [smoke-tests]
runs-on: ubuntu-latest
timeout-minutes: 25

env:
COVERAGE_FILE: coverage-integration.dat

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

- name: Run integration tests
run: pytest -q tests/integration --cov=denbust --cov-report=term-missing --cov-report=

- name: Upload integration coverage data
uses: actions/upload-artifact@v4
with:
name: coverage-integration-data
path: coverage-integration.dat

coverage:
needs: [pre-commit, lint, unit-tests, integration-tests]
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

- name: Download unit coverage data
uses: actions/download-artifact@v4
with:
name: coverage-unit-data
path: coverage-data/unit

- name: Download integration coverage data
uses: actions/download-artifact@v4
with:
name: coverage-integration-data
path: coverage-data/integration

- name: Combine and report coverage
run: |
python -m coverage combine coverage-data/unit/coverage-unit.dat coverage-data/integration/coverage-integration.dat
python -m coverage report --show-missing
python -m coverage xml -o coverage.xml

- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-xml
path: coverage.xml
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ cython_debug/
.abstra/

# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/

Expand Down
3 changes: 3 additions & 0 deletions .pre-commit-ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ci:
autofix_prs: false
autoupdate_schedule: monthly
16 changes: 16 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-merge-conflict
- id: end-of-file-fixer
exclude: ^tests/fixtures/html/
- id: trailing-whitespace
exclude: ^tests/fixtures/html/
- id: check-yaml

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.7
hooks:
- id: ruff
- id: ruff-format
42 changes: 21 additions & 21 deletions docs/product_def.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,24 @@ date: ינואר 2026

במאבק בתעשיית המין בישראל, החוק בעדנו. אסור לסרסר בנשים, גברים וקטינות. אסור להביא א.נשים לעסוק בזנות. אסור להחזיק מקום המשמש לזנות. ובזכות מאבק ארוך-שנים של המטה, אסור גם לצרוך זנות. החוק מייצר תודעה – אך האפקטיביות שלו נבחנת ביחס לאכיפה.

אכיפה חזקה מקדמת הרתעה, מחזקת את הערכים הנורמטיביים באיסור סרסור וצריכת זנות ומצמצת את הביקוש לקיומה של תעשיית המין האפלה. לעומת זאת, אכיפה חלשה או בררנית מורידה מן האפקטיביות של החוק, מעלימה עין להתפשטות הפשיעה ומשאירה נשים ונערות חשופות לניצול קשה. גם השיח הציבורי סביב האכיפה, הסיקור התקשורתי והנרטיב בו, יכולים להשפיע מאוד על התודעה החברתית סביב תעשיית המין.
אכיפה חזקה מקדמת הרתעה, מחזקת את הערכים הנורמטיביים באיסור סרסור וצריכת זנות ומצמצת את הביקוש לקיומה של תעשיית המין האפלה. לעומת זאת, אכיפה חלשה או בררנית מורידה מן האפקטיביות של החוק, מעלימה עין להתפשטות הפשיעה ומשאירה נשים ונערות חשופות לניצול קשה. גם השיח הציבורי סביב האכיפה, הסיקור התקשורתי והנרטיב בו, יכולים להשפיע מאוד על התודעה החברתית סביב תעשיית המין.

פרויקט "מדד האכיפה" יבחן את מאמצי האכיפה של המשטרה בתחום זה ויציג אותם באופן שקוף ומופשט לציבור. כגוף בעל נוכחות תקשורתית ויכולות בתחום התקשורת והמדיה, שיקוף מידע זה יכול להשפיע באופן ממשי על התודעה והשיח הציבורי בתחום. במקביל, המטה יעקוב אחרי הליכים פתוחים ויגיש חוות דעת משפטיות במקרים המתאימים מתוך הידע והניסיון שלנו, במטרה לקדם כתבי אישום.
פרויקט "מדד האכיפה" יבחן את מאמצי האכיפה של המשטרה בתחום זה ויציג אותם באופן שקוף ומופשט לציבור. כגוף בעל נוכחות תקשורתית ויכולות בתחום התקשורת והמדיה, שיקוף מידע זה יכול להשפיע באופן ממשי על התודעה והשיח הציבורי בתחום. במקביל, המטה יעקוב אחרי הליכים פתוחים ויגיש חוות דעת משפטיות במקרים המתאימים מתוך הידע והניסיון שלנו, במטרה לקדם כתבי אישום.

## מטרות הפרויקט ומנגנוני יישום

לפרויקט ארבעה מטרות מרכזיות:

1. פיקוח אזרחי על מצב האכיפה בתחום הסרסור, צריכת זנות וסגירת זירות זנות במטרה למפות את מצב האכיפה ולזהות פערים ולקדם מדיניות מטיבה בהתאם.
2. העלאת מודעות ציבורית למצב האמיתי של המאבק בתעשיית המין תוך שיקוף נתוני אכיפה ותיווך משמעותם לציבור בתקשורת וברשתות של המטה.
2. העלאת מודעות ציבורית למצב האמיתי של המאבק בתעשיית המין תוך שיקוף נתוני אכיפה ותיווך משמעותם לציבור בתקשורת וברשתות של המטה.
3. יצירת לחץ ציבורי במטרה לעודד אכיפה אפקטיבית יותר בתחום.
4. חיזוק שיתוף הפעולה בין המטה לבין גורמי אכיפת החוק, תוך שיתוף ביכולות המשפטיות של המטה וההיכרות העמוקה עם השטח ועם המתרחש ברמה היומיומית בזנות בישראל.

על מנת להגשים מטרות אלו, הפרויקט יכלול מספר מנגנונים מקבילים:

- איסוף מידע
- שיקוף מידע
- תרומת ידע
- איסוף מידע
- שיקוף מידע
- תרומת ידע

### איסוף מידע

Expand Down Expand Up @@ -78,7 +78,7 @@ date: ינואר 2026

אופן איסוף המידע ייעשה בשלבים. בתחילת הפרויקט, המידע ייאסף מחיפושים ידניים במאגרי מידע משפטיים על בסיס מנוי ומניהול התראות גוגל כדי לגלות על פרסומים תקשורתיים בתחום ועל אירועים שיש לעקוב אחריהם. לצד פעולות אלו, ייבנה פורמט להגשת בקשות חופש מידע אודות המידע שלא זמין לציבור הרחב וייקבע תדירות הגשת הבקשות על מנת לחשוף את הנתונים העדכניים והרלוונטיים ביותר. בעת הצורך, המטה ייעזר באסטרטגיות הלובי שלו כדי להבטיח כי המידע שגורמי אכיפת חוק מחויבים למסור יימסר.

במהלך התנעת הפרויקט, יחד עם יועצות ויועצים מתחום הסייבר ומתחום אכיפת החוק, יאופיין כלי אשר מסוגל לרכז את המידע מאת מקורות מידע משפטיים ותקשורתיים. הכלי יסרוק מאגרים פתוחים על מנת לרכז את ההליכים ופריטי המידע הרלוונטיים. כיום אין מאגר אחד אשר מרכז את המידע אודות מצב האכיפה, ועל מנת להבין את המצב יש צורך לקרוא כתבות והודעות דוברות ולחבר את המידע באופן ידני, ולהשלים את החוסרים בתהליך של בקשת חופש מידע. תהליך זה מורכב ודורש זמן רב, אך אוטומציה של החיפוש יכולה לייעל אותו באופן משמעותי. מתוך סקירה ראשונית, מסתמן כי לא ניתן לבנות כלי אשר יפעל בתוך מאגרי מידע סגורים (למשל, נבו או תקדין) אך כי, במגבלות מסוימות, יהיה ניתן להפעיל כלי כזה באתר של הרשות השופטת, שכן הפרסומים שם פומביים ופתוחים לציבור הרחב, ולצידו גם בפלטפורמות תקשורתיות. לאחר אפיון ובחינת הסוגיות המשפטיות והטכנולוגיות, הכלי ייבנה במסגרת הפרויקט.
במהלך התנעת הפרויקט, יחד עם יועצות ויועצים מתחום הסייבר ומתחום אכיפת החוק, יאופיין כלי אשר מסוגל לרכז את המידע מאת מקורות מידע משפטיים ותקשורתיים. הכלי יסרוק מאגרים פתוחים על מנת לרכז את ההליכים ופריטי המידע הרלוונטיים. כיום אין מאגר אחד אשר מרכז את המידע אודות מצב האכיפה, ועל מנת להבין את המצב יש צורך לקרוא כתבות והודעות דוברות ולחבר את המידע באופן ידני, ולהשלים את החוסרים בתהליך של בקשת חופש מידע. תהליך זה מורכב ודורש זמן רב, אך אוטומציה של החיפוש יכולה לייעל אותו באופן משמעותי. מתוך סקירה ראשונית, מסתמן כי לא ניתן לבנות כלי אשר יפעל בתוך מאגרי מידע סגורים (למשל, נבו או תקדין) אך כי, במגבלות מסוימות, יהיה ניתן להפעיל כלי כזה באתר של הרשות השופטת, שכן הפרסומים שם פומביים ופתוחים לציבור הרחב, ולצידו גם בפלטפורמות תקשורתיות. לאחר אפיון ובחינת הסוגיות המשפטיות והטכנולוגיות, הכלי ייבנה במסגרת הפרויקט.

בשביל לשקף את המידע, במסגרת התנעת הפרויקט הצוות ייעצב עמוד אינטרנט בו יוצג כל המידע. המידע יוצג באופן אסטטי, מונגש לציבור ומנותח לפי תבחינים מהותיים וכמותיים. התצוגה תכלול, בין היתר:

Expand All @@ -88,7 +88,7 @@ date: ינואר 2026
- כמות ההליכים הפליליים בכל תחום ועדכונים בהתאם לפומביות המידע
- ניתוח מהותי של נתונים – היקף צווי הסגירה שניתנו ללא חלוקת קנסות; היקף צווי הסגירה שניתנו במסגרתם נעצרו א.נשים ממעגל הזנות; ועוד

כך, המידע הסטטיסטי יהיה זמין לציבור המתעניינים ולכלי תקשורת הסוקרים את התופעה, וכמו כן המטה יוכל לתאר את מצב המאבק, פערים בין גופי אכיפה או מחוזות שונים, מגמת ההתעמרות בא.נשים במעגל הזנות, וכו'.
כך, המידע הסטטיסטי יהיה זמין לציבור המתעניינים ולכלי תקשורת הסוקרים את התופעה, וכמו כן המטה יוכל לתאר את מצב המאבק, פערים בין גופי אכיפה או מחוזות שונים, מגמת ההתעמרות בא.נשים במעגל הזנות, וכו'.

## ניהול הפרויקט

Expand All @@ -108,20 +108,20 @@ date: ינואר 2026

### תכלול הפרויקט (שוטף)

- תכלול הנתונים והמידע
- ? אחוז משרה מנהלת אכיפה + מנהלת דוברות + מנהלת קשרי ממשל
- עלות ניהול הכלי בשוטף
- תכלול הנתונים והמידע
- ? אחוז משרה מנהלת אכיפה + מנהלת דוברות + מנהלת קשרי ממשל
- עלות ניהול הכלי בשוטף

- ניהול השיח השוטף עם הקואליציה
- ? אחוז משרה מנהלת אכיפה + מנהלת קואליציה
- ניהול השיח השוטף עם הקואליציה
- ? אחוז משרה מנהלת אכיפה + מנהלת קואליציה

- ניהול האתר, הרשתות החברתיות ותחום התקשורת
- ? אחוז משרה מנהלת דוברות + מנהלת אכיפה
- ניהול האתר, הרשתות החברתיות ותחום התקשורת
- ? אחוז משרה מנהלת דוברות + מנהלת אכיפה

- מעקב אחרי ההליכים והשתתפות במקרים המתאימים
- הגשת מידע/חוות דעת במקרים המתאימים; הגשת בקשה להצטרף כידיד בית משפט בעת הצורך וכאשר רלוונטי
- בנוסף, חיזוק הקשר עם המשטרה והפרקליטות באמצעות שיח שוטף
- ? אחוז משרה מנהלת אכיפה
- מעקב אחרי ההליכים והשתתפות במקרים המתאימים
- הגשת מידע/חוות דעת במקרים המתאימים; הגשת בקשה להצטרף כידיד בית משפט בעת הצורך וכאשר רלוונטי
- בנוסף, חיזוק הקשר עם המשטרה והפרקליטות באמצעות שיח שוטף
- ? אחוז משרה מנהלת אכיפה

## מדידת השפעת הפרויקט

Expand All @@ -132,5 +132,5 @@ date: ינואר 2026
3. מעקב אחרי נתוני האכיפה ומגמת עלייה של פעולות האכיפה לאחר הפעלת המדד לתקופה ממושכת.
4. כמות ההליכים בהם המטה השתתף וההשפעה של המטה באותם הליכים.

- מועד מדידה: שנה לאחר עליית המדד לאוויר
- משאב נדרש: עלות מדידה
- מועד מדידה: שנה לאחר עליית המדד לאוויר
- משאב נדרש: עלות מדידה
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ dependencies = [
dev = [
"pytest>=8.0.0",
"pytest-asyncio>=0.24.0",
"pytest-cov>=5.0.0",
"respx>=0.21.0",
"pytest-mock>=3.12.0",
"pre-commit>=3.7.0",
"ruff>=0.5.0",
"mypy>=1.10.0",
"types-beautifulsoup4>=4.12.0",
Expand Down
2 changes: 1 addition & 1 deletion src/denbust/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

from denbust.classifier.relevance import Classifier, create_classifier
from denbust.config import Config, SourceType, load_config
from denbust.dedup.similarity import Deduplicator, create_deduplicator
from denbust.data_models import ClassifiedArticle, RawArticle, UnifiedItem
from denbust.dedup.similarity import Deduplicator, create_deduplicator
from denbust.output.formatter import print_items
from denbust.sources.base import Source
from denbust.sources.maariv import create_maariv_source
Expand Down
Loading