Skip to content
Closed

... #42

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
26 changes: 26 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/plugin_submission.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Plugin Submission Template

## Plugin Information
- **Name**:
- **ID**: (Must be unique, lowercase, no spaces)
- **Version**:
- **Description**:
- **Author**:
- **Language**:

## Checklist
- [ ] Wtyczka znajduje się w osobnym folderze wewnątrz `data/`.
- [ ] `manifest.json` jest poprawny i zawiera wszystkie wymagane pola (id, name, version, description, author, dependencies).
- [ ] `plugin.weeb` jest obecny i funkcjonalny.
- [ ] `README.md` zawiera szczegółowe instrukcje użytkowania.
- [ ] W folderze `screenshots/` znajduje się co najmniej jedno zdjęcie.
- [ ] W folderze `assets/` znajduje się ikona wtyczki (`icon.png`).
- [ ] Brak złośliwego kodu lub nieautoryzowanego zbierania danych.
- [ ] Wtyczka została przetestowana lokalnie i działa zgodnie z oczekiwaniami.
- [ ] Testy wtyczki przechodzą poprawnie (min. 80% coverage).

## Screenshots / Demo
(Optional but recommended)

## Additional Notes
(Any extra information about the plugin)
83 changes: 83 additions & 0 deletions .github/workflows/plugin_validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Plugin Validation

on:
pull_request:
paths:
- 'data/**'

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install jsonschema pyyaml bandit ruff coverage pytest

- name: Validate Plugin Structure
run: |
for plugin_dir in data/*/; do
if [ -d "$plugin_dir" ]; then
echo "Validating $plugin_dir..."

# Check manifest.json
if [ ! -f "$plugin_dir/manifest.json" ]; then
echo "Error: manifest.json missing in $plugin_dir"
exit 1
fi

# Check required manifest fields
python3 -c "import json, sys; m = json.load(open('$plugin_dir/manifest.json')); req = ['id', 'name', 'version', 'description', 'author', 'dependencies']; missing = [f for f in req if f not in m]; sys.exit(f'Missing {missing}') if missing else sys.exit(0)" || exit 1

# Check entry point
ENTRY_POINT=$(python3 -c "import json; print(json.load(open('$plugin_dir/manifest.json')).get('entry_point', 'plugin.weeb'))")
if [ ! -f "$plugin_dir/$ENTRY_POINT" ]; then
echo "Error: Entry point $ENTRY_POINT missing in $plugin_dir"
exit 1
fi

# Check README.md
if [ ! -f "$plugin_dir/README.md" ]; then
echo "Error: README.md missing in $plugin_dir"
exit 1
fi

# Check screenshots dir
if [ ! -d "$plugin_dir/screenshots" ] || [ -z "$(ls -A $plugin_dir/screenshots)" ]; then
echo "Error: screenshots directory missing or empty in $plugin_dir"
exit 1
fi
fi
done

- name: Security Scan (Bandit)
run: |
bandit -r data/

- name: Linting (Ruff)
run: |
ruff check data/

- name: Run Tests & Check Coverage
run: |
# Bug 0009: Use --append to accumulate coverage data across plugins
for plugin_dir in data/*/; do
if [ -d "$plugin_dir" ] && [ -d "$plugin_dir/tests" ]; then
echo "Running tests for $plugin_dir"
coverage run --append -m pytest $plugin_dir/tests/
fi
done
# Only fail if total coverage is under 80% (or adjust as needed)
if [ -f .coverage ]; then
coverage report --fail-under=80
fi

- name: Validation Successful
run: echo "Plugin validation passed!"
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@

## Features

### Plugin System
- **Custom .weeb format**: Package and share your own providers
- **Secure Sandbox**: Run plugins safely with restricted permissions
- **Plugin Builder**: Easy-to-use script for packaging plugins
- **Plugin Gallery**: Browse and install community plugins from [Gallery](plugin_gallery/index.html)
- **Automatic Discovery**: Plugins are loaded automatically on startup

### Multiple Sources
- **Turkish**: Animecix, Turkanime, Anizle, Weeb
- **English**: HiAnime, AllAnime
Expand Down Expand Up @@ -278,6 +285,8 @@ All settings can be modified through the interactive Settings menu.
- [x] Non-interactive API mode (JSON output)
- [x] Torznab server for Sonarr/*arr integration
- [x] RESTful API server for web/mobile apps
- [x] Plugin System with Sandbox support
- [x] Plugin Builder & Gallery site


### Planned
Expand Down
13 changes: 13 additions & 0 deletions data/ornek_plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Örnek Plugin

Weeb CLI için örnek bir anime sağlayıcısı eklentisi.

## Özellikler
- Arama simülasyonu
- Sahte bölümler ve video bağlantıları
- Yeni plugin standartlarına uyumlu yapı

## Geliştirici Bilgileri
- **Yazar**: Geliştirici Adı
- **Versiyon**: 1.0.0
- **Bağımlılıklar**: Yok
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions data/ornek_plugin/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"id": "ornek-plugin",
"name": "Örnek Plugin",
"version": "1.0.0",
"description": "Weeb CLI için örnek bir sağlayıcı eklentisi.",
"author": "Geliştirici Adı",
"entry_point": "plugin.weeb",
"min_weeb_version": "1.0.0",
"dependencies": [],
"permissions": ["network"],
"tags": ["anime", "türkçe", "sağlayıcı"],
"icon": "assets/icon.png",
"homepage": "https://github.com/ewgsta/weeb-cli",
"repository_url": "https://github.com/ewgsta/weeb-cli",
"license": "GPL-3.0"
}
24 changes: 24 additions & 0 deletions data/ornek_plugin/plugin.weeb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
def register():
"""Örnek sağlayıcıyı Weeb CLI'ye kaydeder."""
from weeb_cli.providers.registry import register_provider
from weeb_cli.providers.base import BaseProvider

@register_provider("ornek_plugin", lang="tr", region="TR")
class OrnekProvider(BaseProvider):
def __init__(self):
super().__init__()
self.name = "ornek_plugin"

def search(self, query: str):
"""Arama işlevi örneği."""
return [{"title": f"Örnek Sonuç: {query}", "id": "ornek-123"}]

def get_episodes(self, anime_id: str):
"""Bölüm getirme örneği."""
return [{"id": "bolum-1", "title": "1. Bölüm"}]

def get_streams(self, ep_id: str):
"""Video bağlantısı getirme örneği."""
return [{"url": "https://ornek.com/video.mp4", "quality": "1080p"}]

print("[Örnek Plugin] Başarıyla yüklendi ve kaydedildi!")
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
91 changes: 91 additions & 0 deletions docs/development/plugins.de.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Plugin-Entwicklungsleitfaden

Weeb CLI bietet eine robuste Plugin-Architektur, mit der Sie die Anwendung durch benutzerdefinierte Anbieter, Tracker und Dienste erweitern können. Plugins sind in einer sicheren, portablen Umgebung isoliert und folgen einer standardisierten Verzeichnisstruktur.

## Plugin-Struktur

Ein Standard-Plugin-Ordner muss im Verzeichnis `data/` gespeichert sein und die folgende Struktur aufweisen:

```
data/
mein-plugin/
plugin.weeb (Haupt-Code-Einstiegspunkt)
manifest.json (Metadaten und Konfiguration)
README.md (Detaillierte Dokumentation)
screenshots/ (Mindestens ein Screenshot für die Galerie)
ss1.png
assets/ (Icons und andere Assets)
icon.png
```

### manifest.json

Das Manifest enthält obligatorische und optionale Metadaten über Ihr Plugin:

```json
{
"id": "mein-plugin",
"name": "Mein Plugin",
"version": "1.0.0",
"description": "Eine Beschreibung Ihres Plugins.",
"author": "Ihr Name",
"entry_point": "plugin.weeb",
"min_weeb_version": "1.0.0",
"dependencies": [],
"permissions": ["network", "storage"],
"tags": ["anime", "de"],
"icon": "assets/icon.png",
"homepage": "https://example.com",
"repository_url": "https://github.com/user/repo",
"license": "MIT"
}
```

### plugin.weeb

Der Einstiegspunkt ist ein Python-Skript, das eine `register()`-Funktion definieren muss. Es läuft in einer eingeschränkten Sandbox-Umgebung mit Zugriff auf eine sichere Untermenge von Builtins und `weeb_cli`-APIs.

```python
def register():
from weeb_cli.providers.registry import register_provider
from weeb_cli.providers.base import BaseProvider

@register_provider("mein_benutzerdefinierter_anbieter", lang="de", region="DE")
class MyProvider(BaseProvider):
def search(self, query: str):
# Implementierung...
pass
```

## Erstellung und Paketierung

Verwenden Sie das bereitgestellte Builder-Skript, um neue Plugins zu erstellen oder zu paketieren:

```bash
# Erstellen Sie eine neue Plugin-Vorlage
python3 weeb_cli/utils/plugin_builder.py create mein-neues-plugin --id "neue-id" --name "Neuer Name"

# Erstellen/Paketieren Sie ein Plugin für die Verteilung (.weeb_pkg)
python3 weeb_cli/utils/plugin_builder.py build data/mein-plugin -o mein-plugin.weeb_pkg
```

## Installation

1. Öffnen Sie Weeb CLI.
2. Gehen Sie zu **Einstellungen** > **Plugins**.
3. Wählen Sie **Plugin laden**.
4. Geben Sie den lokalen Pfad zum Plugin-Ordner oder dessen `.weeb_pkg` an.

## Testen und Qualität

Plugins müssen eine **Testabdeckung von mindestens 80 %** aufweisen, um in die offizielle Galerie aufgenommen zu werden. Automatisierte Tests sollten in einem Verzeichnis `tests/` innerhalb des Plugin-Ordners platziert werden.

Unsere CI/CD-Pipeline validiert:
- **Manifest-Integrität**: Erforderliche Felder (ID, Name, Version usw.) müssen vorhanden sein.
- **Sicherheit**: Überprüfung durch Bandit auf häufige Schwachstellen.
- **Codequalität**: Überprüfung durch Ruff.
- **Funktionalität**: Tests werden ausgeführt und die Abdeckung wird geprüft.

## Teilen über die Galerie

Reichen Sie einen Pull Request ein, um Ihren Plugin-Ordner zum Verzeichnis `data/` hinzuzufügen. Sobald er genehmigt wurde, erscheint er automatisch in der [Plugin-Galerie](https://ewgsta.github.io/weeb-cli/plugin_gallery/index.html).
91 changes: 91 additions & 0 deletions docs/development/plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Plugin Development Guide

Weeb CLI provides a robust plugin architecture that allows you to extend the application with custom providers, trackers, and services. Plugins are isolated in a secure, portable environment and follow a standardized directory structure.

## Plugin Structure

A standard plugin folder must be stored in the `data/` directory and contain the following structure:

```
data/
my-plugin/
plugin.weeb (Main code entry point)
manifest.json (Metadata and configuration)
README.md (Detailed documentation)
screenshots/ (At least one screenshot for the gallery)
ss1.png
assets/ (Icons and other assets)
icon.png
```

### manifest.json

The manifest contains mandatory and optional metadata about your plugin:

```json
{
"id": "my-plugin",
"name": "My Plugin",
"version": "1.0.0",
"description": "A description of your plugin.",
"author": "Your Name",
"entry_point": "plugin.weeb",
"min_weeb_version": "1.0.0",
"dependencies": [],
"permissions": ["network", "storage"],
"tags": ["anime", "en"],
"icon": "assets/icon.png",
"homepage": "https://example.com",
"repository_url": "https://github.com/user/repo",
"license": "MIT"
}
```

### plugin.weeb

The entry point is a Python script that must define a `register()` function. It runs in a restricted sandbox environment with access to a safe subset of builtins and `weeb_cli` APIs.

```python
def register():
from weeb_cli.providers.registry import register_provider
from weeb_cli.providers.base import BaseProvider

@register_provider("my_custom_provider", lang="en", region="US")
class MyProvider(BaseProvider):
def search(self, query: str):
# Implementation...
pass
```

## Building and Packaging

Use the provided builder script to package or create new plugins:

```bash
# Create a new plugin template
python3 weeb_cli/utils/plugin_builder.py create my-new-plugin --id "new-id" --name "New Name"

# Build/Package a plugin for distribution (.weeb_pkg)
python3 weeb_cli/utils/plugin_builder.py build data/my-plugin -o my-plugin.weeb_pkg
```

## Installation

1. Open Weeb CLI.
2. Go to **Settings** > **Plugins**.
3. Select **Load Plugin**.
4. Provide the local path to the plugin folder or its `.weeb_pkg`.

## Testing and Quality

Plugins must maintain at least **80% test coverage** to be accepted into the official gallery. Automated tests should be placed in a `tests/` directory within the plugin folder.

Our CI/CD pipeline validates:
- **Manifest integrity**: Required fields (id, name, version, etc.) must be present.
- **Security**: Scanned via Bandit for common vulnerabilities.
- **Code Quality**: Linted via Ruff.
- **Functionality**: Tests are executed, and coverage is checked.

## Sharing via Gallery

Submit a Pull Request adding your plugin folder to the `data/` directory. Once approved, it will automatically appear in the [Plugin Gallery](https://ewgsta.github.io/weeb-cli/plugin_gallery/index.html).
Loading
Loading