mailopt


Namemailopt JSON
Version 0.1.0 PyPI version JSON
download
home_pagehttps://github.com/vml-marketing-mail/mailopt
SummaryCLI Python pour automatiser et optimiser les workflows email/front-end
upload_time2025-07-22 17:39:43
maintainerNone
docs_urlNone
authorSouleymane SALL
requires_python>=3.10
licenseNone
keywords email cli automation optimization frontend workflow
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # MailOpt

[![CI](https://github.com/your-username/mailopt/workflows/CI/badge.svg)](https://github.com/your-username/mailopt/actions)
[![Coverage](https://codecov.io/gh/your-username/mailopt/branch/master/graph/badge.svg)](https://codecov.io/gh/your-username/mailopt)
[![PyPI](https://img.shields.io/pypi/v/mailopt.svg)](https://pypi.org/project/mailopt/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)

**CLI Python pour automatiser et optimiser les workflows email/front-end**

## Table des matières

- [Motivation & Contexte](#motivation--contexte)
- [Fonctionnalités clés](#fonctionnalités-clés)
- [Installation](#installation)
- [Usage rapide](#usage-rapide)
- [Détail des commandes](#détail-des-commandes)
- [Configuration](#configuration)
- [Extensibilité & Plugins](#extensibilité--plugins)
- [Développement & Tests](#développement--tests)
- [Outils de développement](#outils-de-développement)
- [CI/CD](#cicd)
- [Workflow Git & Contribuer](#workflow-git--contribuer)
- [Roadmap & Perspectives](#roadmap--perspectives)
- [Licence](#licence)
- [Contacts & Liens](#contacts--liens)

## Motivation & Contexte

### Pourquoi créer mailopt ?

Le développement d'emails implique de nombreuses tâches répétitives et chronophages qui fragmentent le workflow des développeurs. `mailopt` naît du besoin d'unifier et d'automatiser ces processus pour permettre aux équipes de se concentrer sur la création de contenu de qualité.

### Problèmes résolus

- **Inlining CSS manuel** → Automatisation complète avec `mailopt inline`
- **Validation d'assets** → Vérification automatique des images et liens
- **Tests de compatibilité** → Intégration Litmus et captures d'écran
- **Optimisation manuelle** → Minification et optimisation automatiques
- **Workflow fragmenté** → Unification de tous les outils d'optimisation email

## Fonctionnalités clés

### Commandes cœur

| Commande                              | Description                                               |
| ------------------------------------- | --------------------------------------------------------- |
| **`mailopt new <dir>`**               | Génère la structure de base d'un projet email/site        |
| **`mailopt inline <dir>`**            | Inline CSS pour templates email-safe                      |
| **`mailopt check-images <dir>`**      | Vérifie existence & casse des images référencées          |
| **`mailopt embed-images <dir>`**      | Encode en Base64 / upload CDN et remplace balises `<img>` |
| **`mailopt check-links <dir>`**       | Head-request et rapport sur les liens `<a>`               |
| **`mailopt find-orphans <dir>`**      | Liste fichiers assets non utilisés                        |
| **`mailopt lint-names <dir>`**        | Vérifie conventions de nommage                            |
| **`mailopt unused-css <dir>`**        | Détecte sélecteurs CSS non utilisés                       |
| **`mailopt minify <dir>`**            | Concatène & minifie CSS/JS selon manifest                 |
| **`mailopt audit <dir>`**             | Audit d'accessibilité & rapport spam-score                |
| **`mailopt snapshot <dir>`**          | Génère captures (desktop/mobile) via Playwright           |
| **`mailopt merge-tags <csv> <tmpl>`** | Génère HTML personnalisés depuis CSV                      |
| **`mailopt litmus <dir>`**            | Lance les tests email sur Litmus via l'API                |

## Installation

### Prérequis

- Python ≥ 3.10
- pip

### Installation

```bash
# Cloner le repository
git clone https://github.com/your-username/mailopt.git
cd mailopt

# Créer un environnement virtuel
python -m venv venv

# Activer l'environnement virtuel
# Windows
venv\Scripts\activate
# macOS/Linux
source venv/bin/activate

# Installation avec toutes les dépendances
pip install -r requirements.txt

# Ou installation en mode développement
pip install -r requirements-dev.txt
pip install -e .

# Ou depuis PyPI (quand publié)
pip install mailopt
```

## Usage rapide

### Exemples de base

```bash
# Créer un nouveau projet email
mailopt new ./my-email

# Inliner le CSS pour compatibilité email
mailopt inline ./my-email

# Vérifier les images avec correction automatique
mailopt check-images ./my-email --fix
```

### Flags généraux

```bash
mailopt --help      # Aide générale
mailopt --version   # Version du CLI
mailopt <command> --help  # Aide pour une commande spécifique
```

## Détail des commandes

### `mailopt check-images <dir> [--fix]`

**Objectif :** Vérifie existence & casse des images référencées

**Options :**

- `--fix` : Corriger automatiquement les problèmes détectés
- `--verbose` : Affichage détaillé
- `--suggest-formats` : Suggérer des formats optimisés

**Exemple :**

```bash
mailopt check-images ./email.html --fix --verbose
```

**Fonctionnalités :**

- Détecte toutes les balises `<img src="...">` locales
- Vérifie que les images existent dans `images/` ou `img/`
- Corrige automatiquement les problèmes de casse
- Crée une sauvegarde `.bak` lors des corrections
- Ignore les URLs externes (http://, https://, //)

## Configuration

### Format de `mailopt.config.yaml`

```yaml
# mailopt.config.yaml
defaults:
  image_quality: 85
  output_format: webp
  preserve_metadata: false
  email_clients: [outlook, gmail, apple-mail, thunderbird]

commands:
  check_images:
    max_width: 1200
    max_height: 800
    allowed_formats: [jpg, png, webp]
    check_case_sensitivity: true

paths:
  templates: ./templates/
  assets: ./assets/
  output: ./dist/
  reports: ./reports/
```

## Extensibilité & Plugins

### Architecture plugin via entry_points

`mailopt` utilise un système de plugins basé sur les `entry_points` de Python pour charger automatiquement les commandes.

### Ajouter sa propre commande

1. **Créer un fichier de commande** dans `mailopt/commands/` :

```python
# mailopt/commands/my_command.py
import click
from mailopt import utils

@click.command()
@click.option('--name', default='world', help='Nom à saluer')
def my_command(name):
    """Ma commande personnalisée."""
    click.echo(f"Bonjour, {name}!")
    # Votre logique ici
```

2. **Enregistrer la commande** dans `setup.py` :

```python
# setup.py
entry_points={
    'console_scripts': [
        'mailopt=mailopt.cli:main',
    ],
    'mailopt.commands': [
        'my-command=mailopt.commands.my_command:my_command',
    ],
}
```

3. **Utiliser votre commande** :

```bash
mailopt my-command --name "Développeur"
```

## Développement & Tests

### Structure du repo

```
mailopt/
├── setup.py              # Metadata & entry_points
├── pyproject.toml        # Build system
├── requirements.txt      # Toutes les dépendances
├── requirements-dev.txt  # Dépendances de développement
├── README.md             # Documentation
├── .gitignore            # Fichiers à ignorer par Git
├── mailopt/              # Code source
│   ├── __init__.py
│   ├── cli.py            # Point d'entrée (click.group)
│   ├── utils.py          # Fonctions utilitaires partagées
│   └── commands/         # Sous-commandes
│       ├── __init__.py
│       └── images.py     # Exemple: check-images
├── tests/                # Tests unitaires (pytest)
│   └── test_images.py
└── venv/                 # Environnement virtuel (ignoré par Git)
```

### Fichiers de dépendances

- **`requirements.txt`** : Toutes les dépendances (core + dev)
- **`requirements-dev.txt`** : Dépendances de développement uniquement
- **`setup.py`** : Configuration du package avec entry points

### Fichiers et dossiers ignorés

Le projet utilise un `.gitignore` simple qui exclut :

- **`*.egg-info/`** : Métadonnées générées par setuptools lors de l'installation
- **`venv/`** : Environnement virtuel Python
- **`__pycache__/`** : Cache Python compilé
- **`.pytest_cache/`** : Cache des tests pytest
- **`*.bak`** : Fichiers de sauvegarde créés par mailopt
- **Fichiers IDE** : `.vscode/`, `.idea/`, etc.
- **Fichiers système** : `.DS_Store`, `Thumbs.db`

### Le dossier `mailopt.egg-info`

Le dossier `mailopt.egg-info/` est **automatiquement généré** par setuptools lors de l'installation du package avec `pip install -e .`. Il contient :

- **Métadonnées du package** : version, auteur, description
- **Liste des fichiers** : fichiers inclus dans le package
- **Entry points** : commandes CLI enregistrées
- **Dépendances** : packages requis

**Pourquoi l'ignorer ?**

- Généré automatiquement, pas besoin de versionner
- Spécifique à l'environnement d'installation
- Peut causer des conflits entre développeurs
- Reconstruit automatiquement lors de l'installation

### Lancer les tests

```bash
# Tous les tests
pytest tests/

# Avec couverture
pytest --cov=mailopt tests/

# Tests spécifiques
pytest tests/test_images.py -v

# Tests avec marqueurs
pytest -m "not slow"  # Exclure les tests lents
pytest -m integration # Tests d'intégration uniquement
```

## Outils de développement

### Formateurs de code

#### **Black** - Formateur de code automatique

```bash
# Installer Black
pip install black

# Formater le code
black mailopt/ tests/

# Vérifier le formatage (sans modifier)
black --check mailopt/ tests/

# Configuration dans pyproject.toml
[tool.black]
line-length = 88
target-version = ['py310']
include = '\.pyi?$'
extend-exclude = '''
/(
  # directories
  \.eggs
  | \.git
  | \.hg
  | \.mypy_cache
  | \.tox
  | \.venv
  | build
  | dist
)/
'''
```

#### **isort** - Organisation des imports

```bash
# Installer isort
pip install isort

# Organiser les imports
isort mailopt/ tests/

# Configuration dans pyproject.toml
[tool.isort]
profile = "black"
multi_line_output = 3
line_length = 88
```

### Linters et analyseurs

#### **Flake8** - Linter PEP8

```bash
# Installer Flake8
pip install flake8

# Linter le code
flake8 mailopt/ tests/

# Configuration dans .flake8
[flake8]
max-line-length = 88
extend-ignore = E203, W503
exclude = .git,__pycache__,build,dist,*.egg-info
```

#### **Pylint** - Analyseur statique avancé

```bash
# Installer Pylint
pip install pylint

# Analyser le code
pylint mailopt/

# Générer un rapport
pylint mailopt/ --output-format=json > pylint-report.json

# Configuration dans .pylintrc
[MASTER]
disable=
    C0114, # missing-module-docstring
    C0115, # missing-class-docstring
    C0116  # missing-function-docstring
```

#### **MyPy** - Vérificateur de types statiques

```bash
# Installer MyPy
pip install mypy

# Vérifier les types
mypy mailopt/ --ignore-missing-imports

# Configuration dans pyproject.toml
[tool.mypy]
python_version = "3.10"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
```

### Tests et couverture

#### **Pytest** - Framework de tests

```bash
# Installer Pytest
pip install pytest pytest-cov pytest-mock

# Lancer les tests
pytest tests/ -v

# Avec couverture
pytest --cov=mailopt --cov-report=html tests/

# Tests en parallèle
pytest -n auto tests/

# Configuration dans pytest.ini
[tool:pytest]
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = -v --tb=short --strict-markers
markers =
    slow: marks tests as slow
    integration: marks tests as integration tests
```

#### **Coverage.py** - Mesure de couverture

```bash
# Installer Coverage
pip install coverage

# Mesurer la couverture
coverage run -m pytest tests/
coverage report
coverage html  # Génère un rapport HTML

# Configuration dans .coveragerc
[run]
source = mailopt
omit =
    */tests/*
    */venv/*
    setup.py
```

### Outils de build et publication

#### **Build** - Construction de packages

```bash
# Installer Build
pip install build

# Construire le package
python -m build

# Vérifier le package
twine check dist/*
```

#### **Twine** - Publication sur PyPI

```bash
# Installer Twine
pip install twine

# Publier sur TestPyPI
twine upload --repository testpypi dist/*

# Publier sur PyPI
twine upload dist/*
```

### Outils de sécurité

#### **Bandit** - Détection de vulnérabilités

```bash
# Installer Bandit
pip install bandit

# Analyser la sécurité
bandit -r mailopt/

# Configuration dans .bandit
[bandit]
exclude_dirs = tests
skips = B101, B601
```

#### **Safety** - Vérification des dépendances

```bash
# Installer Safety
pip install safety

# Vérifier les vulnérabilités (commande dépréciée)
safety check

# Vérifier avec la nouvelle commande (recommandé)
# Note: Nécessite un compte Safety CLI (gratuit)
safety scan

# Première utilisation: Safety demandera de créer un compte
# Suivez les instructions pour vous enregistrer
```

### Workflow complet de développement

#### **Script de pré-commit**

```bash
#!/bin/bash
# .git/hooks/pre-commit

echo "🔍 Vérification du code..."

# Formater le code
black mailopt/ tests/
isort mailopt/ tests/

# Linter
flake8 mailopt/ tests/
pylint mailopt/ --score=8.0

# Vérifier les types
mypy mailopt/ --ignore-missing-imports

# Tests rapides
pytest tests/ -x --tb=short

echo "✅ Pré-commit terminé avec succès!"
```

#### **Script de CI complet**

```bash
#!/bin/bash
# scripts/ci.sh

set -e

echo "🚀 Démarrage du CI..."

# Installer les dépendances
pip install -e ".[dev,test]"

# Formater et vérifier
black --check mailopt/ tests/
isort --check-only mailopt/ tests/

# Linter
flake8 mailopt/ tests/
pylint mailopt/ --score=8.0

# Vérifier les types
mypy mailopt/ --ignore-missing-imports

# Tests avec couverture
pytest --cov=mailopt --cov-report=xml tests/

# Sécurité
bandit -r mailopt/
safety check

# Build
python -m build
twine check dist/*

echo "✅ CI terminé avec succès!"
```

### Configuration des outils

#### **pyproject.toml** - Configuration centralisée

```toml
[build-system]
requires = ["setuptools>=45", "wheel"]
build-backend = "setuptools.build_meta"

[tool.black]
line-length = 88
target-version = ['py310']

[tool.isort]
profile = "black"
line_length = 88

[tool.mypy]
python_version = "3.10"
warn_return_any = true
disallow_untyped_defs = true

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
addopts = "-v --tb=short"
markers = [
    "slow: marks tests as slow",
    "integration: marks tests as integration tests",
]
```

#### **.pre-commit-config.yaml** - Hooks automatiques

```yaml
repos:
  - repo: https://github.com/psf/black
    rev: 23.3.0
    hooks:
      - id: black
        language_version: python3.10

  - repo: https://github.com/pycqa/isort
    rev: 5.12.0
    hooks:
      - id: isort

  - repo: https://github.com/pycqa/flake8
    rev: 6.0.0
    hooks:
      - id: flake8

  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.3.0
    hooks:
      - id: mypy
        additional_dependencies: [types-requests]
```

## CI/CD

### Workflow GitHub Actions

```yaml
# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [3.10, 3.11, 3.12]

    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install dependencies
        run: |
          pip install -e .
          pip install pytest pytest-cov flake8 pylint
      - name: Run tests
        run: pytest --cov=mailopt tests/
      - name: Run linter
        run: |
          flake8 mailopt/ tests/
          pylint mailopt/
```

### Pré-commit hook

```bash
#!/bin/bash
# .git/hooks/pre-commit

# Vérifier les noms de fichiers
mailopt lint-names . --fix

# Trouver les fichiers orphelins
mailopt find-orphans ./assets --dry-run

# Tests rapides
pytest tests/ -x
```

## Workflow Git & Contribuer

### Branche feature

```bash
# Créer une branche feature
git checkout -b feat/amazing-feature

# Commits atomiques
git commit -m "feat: add amazing feature"
git commit -m "test: add tests for amazing feature"
git commit -m "docs: update documentation for amazing feature"
```

### Modèle de message de commit (Conventional Commits)

```
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
```

**Types :**

- `feat` : Nouvelle fonctionnalité
- `fix` : Correction de bug
- `docs` : Documentation
- `style` : Formatage
- `refactor` : Refactoring
- `test` : Tests
- `chore` : Maintenance

**Exemples :**

```bash
git commit -m "feat(inline): add CSS minification option"
git commit -m "fix(check-images): handle case-sensitive file systems"
git commit -m "docs: update installation instructions"
```

## Roadmap & Perspectives

### Fonctionnalités à venir

- **Intégration Litmus avancée** : Tests automatisés sur tous les clients email
- **Merge-tags avancé** : Support de templates complexes et conditions
- **API REST** : Interface web pour les équipes non-techniques
- **Intégration CI/CD** : Plugins pour GitHub Actions, GitLab CI
- **Support multi-langues** : Interface en français, anglais, espagnol
- **Mode watch** : Surveillance en temps réel des fichiers
- **Rapports avancés** : Graphiques et métriques détaillées

### Appel à contributions

Bien que le projet soit actuellement maintenu par un seul développeur, nous encourageons les contributions de la communauté email development. Les domaines prioritaires :

- Tests de compatibilité email
- Optimisation d'images
- Accessibilité
- Documentation
- Intégrations tierces

## Licence

Ce projet est sous licence MIT - voir le fichier [LICENSE](LICENSE) pour les détails.

**MIT License** - Licence permissive permettant :

- Usage commercial
- Modification
- Distribution
- Usage privé

Avec protection de responsabilité pour les auteurs.

## Contacts & Liens

### Issues & Discussions

- **Issues** : [GitHub Issues](https://github.com/your-username/mailopt/issues)
- **Discussions** : [GitHub Discussions](https://github.com/your-username/mailopt/discussions)
- **Wiki** : [Documentation détaillée](https://github.com/your-username/mailopt/wiki)

### Mainteneurs

- **Développeur principal** : [@your-username](https://github.com/your-username)

### Liens utiles

- **PyPI** : [pypi.org/project/mailopt](https://pypi.org/project/mailopt/)
- **Documentation** : [mailopt.readthedocs.io](https://mailopt.readthedocs.io/)
- **Changelog** : [CHANGELOG.md](CHANGELOG.md)

---

**Fait avec ❤️ pour la communauté email development**

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/vml-marketing-mail/mailopt",
    "name": "mailopt",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "email, cli, automation, optimization, frontend, workflow",
    "author": "Souleymane SALL",
    "author_email": "souleymanesallvml@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/52/81/a3fae0ff328a4cf4c1634c10c65c3f42f0932177270dbeba40d26ca4d960/mailopt-0.1.0.tar.gz",
    "platform": null,
    "description": "# MailOpt\n\n[![CI](https://github.com/your-username/mailopt/workflows/CI/badge.svg)](https://github.com/your-username/mailopt/actions)\n[![Coverage](https://codecov.io/gh/your-username/mailopt/branch/master/graph/badge.svg)](https://codecov.io/gh/your-username/mailopt)\n[![PyPI](https://img.shields.io/pypi/v/mailopt.svg)](https://pypi.org/project/mailopt/)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\n**CLI Python pour automatiser et optimiser les workflows email/front-end**\n\n## Table des mati\u00e8res\n\n- [Motivation & Contexte](#motivation--contexte)\n- [Fonctionnalit\u00e9s cl\u00e9s](#fonctionnalit\u00e9s-cl\u00e9s)\n- [Installation](#installation)\n- [Usage rapide](#usage-rapide)\n- [D\u00e9tail des commandes](#d\u00e9tail-des-commandes)\n- [Configuration](#configuration)\n- [Extensibilit\u00e9 & Plugins](#extensibilit\u00e9--plugins)\n- [D\u00e9veloppement & Tests](#d\u00e9veloppement--tests)\n- [Outils de d\u00e9veloppement](#outils-de-d\u00e9veloppement)\n- [CI/CD](#cicd)\n- [Workflow Git & Contribuer](#workflow-git--contribuer)\n- [Roadmap & Perspectives](#roadmap--perspectives)\n- [Licence](#licence)\n- [Contacts & Liens](#contacts--liens)\n\n## Motivation & Contexte\n\n### Pourquoi cr\u00e9er mailopt ?\n\nLe d\u00e9veloppement d'emails implique de nombreuses t\u00e2ches r\u00e9p\u00e9titives et chronophages qui fragmentent le workflow des d\u00e9veloppeurs. `mailopt` na\u00eet du besoin d'unifier et d'automatiser ces processus pour permettre aux \u00e9quipes de se concentrer sur la cr\u00e9ation de contenu de qualit\u00e9.\n\n### Probl\u00e8mes r\u00e9solus\n\n- **Inlining CSS manuel** \u2192 Automatisation compl\u00e8te avec `mailopt inline`\n- **Validation d'assets** \u2192 V\u00e9rification automatique des images et liens\n- **Tests de compatibilit\u00e9** \u2192 Int\u00e9gration Litmus et captures d'\u00e9cran\n- **Optimisation manuelle** \u2192 Minification et optimisation automatiques\n- **Workflow fragment\u00e9** \u2192 Unification de tous les outils d'optimisation email\n\n## Fonctionnalit\u00e9s cl\u00e9s\n\n### Commandes c\u0153ur\n\n| Commande                              | Description                                               |\n| ------------------------------------- | --------------------------------------------------------- |\n| **`mailopt new <dir>`**               | G\u00e9n\u00e8re la structure de base d'un projet email/site        |\n| **`mailopt inline <dir>`**            | Inline CSS pour templates email-safe                      |\n| **`mailopt check-images <dir>`**      | V\u00e9rifie existence & casse des images r\u00e9f\u00e9renc\u00e9es          |\n| **`mailopt embed-images <dir>`**      | Encode en Base64 / upload CDN et remplace balises `<img>` |\n| **`mailopt check-links <dir>`**       | Head-request et rapport sur les liens `<a>`               |\n| **`mailopt find-orphans <dir>`**      | Liste fichiers assets non utilis\u00e9s                        |\n| **`mailopt lint-names <dir>`**        | V\u00e9rifie conventions de nommage                            |\n| **`mailopt unused-css <dir>`**        | D\u00e9tecte s\u00e9lecteurs CSS non utilis\u00e9s                       |\n| **`mailopt minify <dir>`**            | Concat\u00e8ne & minifie CSS/JS selon manifest                 |\n| **`mailopt audit <dir>`**             | Audit d'accessibilit\u00e9 & rapport spam-score                |\n| **`mailopt snapshot <dir>`**          | G\u00e9n\u00e8re captures (desktop/mobile) via Playwright           |\n| **`mailopt merge-tags <csv> <tmpl>`** | G\u00e9n\u00e8re HTML personnalis\u00e9s depuis CSV                      |\n| **`mailopt litmus <dir>`**            | Lance les tests email sur Litmus via l'API                |\n\n## Installation\n\n### Pr\u00e9requis\n\n- Python \u2265 3.10\n- pip\n\n### Installation\n\n```bash\n# Cloner le repository\ngit clone https://github.com/your-username/mailopt.git\ncd mailopt\n\n# Cr\u00e9er un environnement virtuel\npython -m venv venv\n\n# Activer l'environnement virtuel\n# Windows\nvenv\\Scripts\\activate\n# macOS/Linux\nsource venv/bin/activate\n\n# Installation avec toutes les d\u00e9pendances\npip install -r requirements.txt\n\n# Ou installation en mode d\u00e9veloppement\npip install -r requirements-dev.txt\npip install -e .\n\n# Ou depuis PyPI (quand publi\u00e9)\npip install mailopt\n```\n\n## Usage rapide\n\n### Exemples de base\n\n```bash\n# Cr\u00e9er un nouveau projet email\nmailopt new ./my-email\n\n# Inliner le CSS pour compatibilit\u00e9 email\nmailopt inline ./my-email\n\n# V\u00e9rifier les images avec correction automatique\nmailopt check-images ./my-email --fix\n```\n\n### Flags g\u00e9n\u00e9raux\n\n```bash\nmailopt --help      # Aide g\u00e9n\u00e9rale\nmailopt --version   # Version du CLI\nmailopt <command> --help  # Aide pour une commande sp\u00e9cifique\n```\n\n## D\u00e9tail des commandes\n\n### `mailopt check-images <dir> [--fix]`\n\n**Objectif :** V\u00e9rifie existence & casse des images r\u00e9f\u00e9renc\u00e9es\n\n**Options :**\n\n- `--fix` : Corriger automatiquement les probl\u00e8mes d\u00e9tect\u00e9s\n- `--verbose` : Affichage d\u00e9taill\u00e9\n- `--suggest-formats` : Sugg\u00e9rer des formats optimis\u00e9s\n\n**Exemple :**\n\n```bash\nmailopt check-images ./email.html --fix --verbose\n```\n\n**Fonctionnalit\u00e9s :**\n\n- D\u00e9tecte toutes les balises `<img src=\"...\">` locales\n- V\u00e9rifie que les images existent dans `images/` ou `img/`\n- Corrige automatiquement les probl\u00e8mes de casse\n- Cr\u00e9e une sauvegarde `.bak` lors des corrections\n- Ignore les URLs externes (http://, https://, //)\n\n## Configuration\n\n### Format de `mailopt.config.yaml`\n\n```yaml\n# mailopt.config.yaml\ndefaults:\n  image_quality: 85\n  output_format: webp\n  preserve_metadata: false\n  email_clients: [outlook, gmail, apple-mail, thunderbird]\n\ncommands:\n  check_images:\n    max_width: 1200\n    max_height: 800\n    allowed_formats: [jpg, png, webp]\n    check_case_sensitivity: true\n\npaths:\n  templates: ./templates/\n  assets: ./assets/\n  output: ./dist/\n  reports: ./reports/\n```\n\n## Extensibilit\u00e9 & Plugins\n\n### Architecture plugin via entry_points\n\n`mailopt` utilise un syst\u00e8me de plugins bas\u00e9 sur les `entry_points` de Python pour charger automatiquement les commandes.\n\n### Ajouter sa propre commande\n\n1. **Cr\u00e9er un fichier de commande** dans `mailopt/commands/` :\n\n```python\n# mailopt/commands/my_command.py\nimport click\nfrom mailopt import utils\n\n@click.command()\n@click.option('--name', default='world', help='Nom \u00e0 saluer')\ndef my_command(name):\n    \"\"\"Ma commande personnalis\u00e9e.\"\"\"\n    click.echo(f\"Bonjour, {name}!\")\n    # Votre logique ici\n```\n\n2. **Enregistrer la commande** dans `setup.py` :\n\n```python\n# setup.py\nentry_points={\n    'console_scripts': [\n        'mailopt=mailopt.cli:main',\n    ],\n    'mailopt.commands': [\n        'my-command=mailopt.commands.my_command:my_command',\n    ],\n}\n```\n\n3. **Utiliser votre commande** :\n\n```bash\nmailopt my-command --name \"D\u00e9veloppeur\"\n```\n\n## D\u00e9veloppement & Tests\n\n### Structure du repo\n\n```\nmailopt/\n\u251c\u2500\u2500 setup.py              # Metadata & entry_points\n\u251c\u2500\u2500 pyproject.toml        # Build system\n\u251c\u2500\u2500 requirements.txt      # Toutes les d\u00e9pendances\n\u251c\u2500\u2500 requirements-dev.txt  # D\u00e9pendances de d\u00e9veloppement\n\u251c\u2500\u2500 README.md             # Documentation\n\u251c\u2500\u2500 .gitignore            # Fichiers \u00e0 ignorer par Git\n\u251c\u2500\u2500 mailopt/              # Code source\n\u2502   \u251c\u2500\u2500 __init__.py\n\u2502   \u251c\u2500\u2500 cli.py            # Point d'entr\u00e9e (click.group)\n\u2502   \u251c\u2500\u2500 utils.py          # Fonctions utilitaires partag\u00e9es\n\u2502   \u2514\u2500\u2500 commands/         # Sous-commandes\n\u2502       \u251c\u2500\u2500 __init__.py\n\u2502       \u2514\u2500\u2500 images.py     # Exemple: check-images\n\u251c\u2500\u2500 tests/                # Tests unitaires (pytest)\n\u2502   \u2514\u2500\u2500 test_images.py\n\u2514\u2500\u2500 venv/                 # Environnement virtuel (ignor\u00e9 par Git)\n```\n\n### Fichiers de d\u00e9pendances\n\n- **`requirements.txt`** : Toutes les d\u00e9pendances (core + dev)\n- **`requirements-dev.txt`** : D\u00e9pendances de d\u00e9veloppement uniquement\n- **`setup.py`** : Configuration du package avec entry points\n\n### Fichiers et dossiers ignor\u00e9s\n\nLe projet utilise un `.gitignore` simple qui exclut :\n\n- **`*.egg-info/`** : M\u00e9tadonn\u00e9es g\u00e9n\u00e9r\u00e9es par setuptools lors de l'installation\n- **`venv/`** : Environnement virtuel Python\n- **`__pycache__/`** : Cache Python compil\u00e9\n- **`.pytest_cache/`** : Cache des tests pytest\n- **`*.bak`** : Fichiers de sauvegarde cr\u00e9\u00e9s par mailopt\n- **Fichiers IDE** : `.vscode/`, `.idea/`, etc.\n- **Fichiers syst\u00e8me** : `.DS_Store`, `Thumbs.db`\n\n### Le dossier `mailopt.egg-info`\n\nLe dossier `mailopt.egg-info/` est **automatiquement g\u00e9n\u00e9r\u00e9** par setuptools lors de l'installation du package avec `pip install -e .`. Il contient :\n\n- **M\u00e9tadonn\u00e9es du package** : version, auteur, description\n- **Liste des fichiers** : fichiers inclus dans le package\n- **Entry points** : commandes CLI enregistr\u00e9es\n- **D\u00e9pendances** : packages requis\n\n**Pourquoi l'ignorer ?**\n\n- G\u00e9n\u00e9r\u00e9 automatiquement, pas besoin de versionner\n- Sp\u00e9cifique \u00e0 l'environnement d'installation\n- Peut causer des conflits entre d\u00e9veloppeurs\n- Reconstruit automatiquement lors de l'installation\n\n### Lancer les tests\n\n```bash\n# Tous les tests\npytest tests/\n\n# Avec couverture\npytest --cov=mailopt tests/\n\n# Tests sp\u00e9cifiques\npytest tests/test_images.py -v\n\n# Tests avec marqueurs\npytest -m \"not slow\"  # Exclure les tests lents\npytest -m integration # Tests d'int\u00e9gration uniquement\n```\n\n## Outils de d\u00e9veloppement\n\n### Formateurs de code\n\n#### **Black** - Formateur de code automatique\n\n```bash\n# Installer Black\npip install black\n\n# Formater le code\nblack mailopt/ tests/\n\n# V\u00e9rifier le formatage (sans modifier)\nblack --check mailopt/ tests/\n\n# Configuration dans pyproject.toml\n[tool.black]\nline-length = 88\ntarget-version = ['py310']\ninclude = '\\.pyi?$'\nextend-exclude = '''\n/(\n  # directories\n  \\.eggs\n  | \\.git\n  | \\.hg\n  | \\.mypy_cache\n  | \\.tox\n  | \\.venv\n  | build\n  | dist\n)/\n'''\n```\n\n#### **isort** - Organisation des imports\n\n```bash\n# Installer isort\npip install isort\n\n# Organiser les imports\nisort mailopt/ tests/\n\n# Configuration dans pyproject.toml\n[tool.isort]\nprofile = \"black\"\nmulti_line_output = 3\nline_length = 88\n```\n\n### Linters et analyseurs\n\n#### **Flake8** - Linter PEP8\n\n```bash\n# Installer Flake8\npip install flake8\n\n# Linter le code\nflake8 mailopt/ tests/\n\n# Configuration dans .flake8\n[flake8]\nmax-line-length = 88\nextend-ignore = E203, W503\nexclude = .git,__pycache__,build,dist,*.egg-info\n```\n\n#### **Pylint** - Analyseur statique avanc\u00e9\n\n```bash\n# Installer Pylint\npip install pylint\n\n# Analyser le code\npylint mailopt/\n\n# G\u00e9n\u00e9rer un rapport\npylint mailopt/ --output-format=json > pylint-report.json\n\n# Configuration dans .pylintrc\n[MASTER]\ndisable=\n    C0114, # missing-module-docstring\n    C0115, # missing-class-docstring\n    C0116  # missing-function-docstring\n```\n\n#### **MyPy** - V\u00e9rificateur de types statiques\n\n```bash\n# Installer MyPy\npip install mypy\n\n# V\u00e9rifier les types\nmypy mailopt/ --ignore-missing-imports\n\n# Configuration dans pyproject.toml\n[tool.mypy]\npython_version = \"3.10\"\nwarn_return_any = true\nwarn_unused_configs = true\ndisallow_untyped_defs = true\n```\n\n### Tests et couverture\n\n#### **Pytest** - Framework de tests\n\n```bash\n# Installer Pytest\npip install pytest pytest-cov pytest-mock\n\n# Lancer les tests\npytest tests/ -v\n\n# Avec couverture\npytest --cov=mailopt --cov-report=html tests/\n\n# Tests en parall\u00e8le\npytest -n auto tests/\n\n# Configuration dans pytest.ini\n[tool:pytest]\ntestpaths = tests\npython_files = test_*.py\npython_classes = Test*\npython_functions = test_*\naddopts = -v --tb=short --strict-markers\nmarkers =\n    slow: marks tests as slow\n    integration: marks tests as integration tests\n```\n\n#### **Coverage.py** - Mesure de couverture\n\n```bash\n# Installer Coverage\npip install coverage\n\n# Mesurer la couverture\ncoverage run -m pytest tests/\ncoverage report\ncoverage html  # G\u00e9n\u00e8re un rapport HTML\n\n# Configuration dans .coveragerc\n[run]\nsource = mailopt\nomit =\n    */tests/*\n    */venv/*\n    setup.py\n```\n\n### Outils de build et publication\n\n#### **Build** - Construction de packages\n\n```bash\n# Installer Build\npip install build\n\n# Construire le package\npython -m build\n\n# V\u00e9rifier le package\ntwine check dist/*\n```\n\n#### **Twine** - Publication sur PyPI\n\n```bash\n# Installer Twine\npip install twine\n\n# Publier sur TestPyPI\ntwine upload --repository testpypi dist/*\n\n# Publier sur PyPI\ntwine upload dist/*\n```\n\n### Outils de s\u00e9curit\u00e9\n\n#### **Bandit** - D\u00e9tection de vuln\u00e9rabilit\u00e9s\n\n```bash\n# Installer Bandit\npip install bandit\n\n# Analyser la s\u00e9curit\u00e9\nbandit -r mailopt/\n\n# Configuration dans .bandit\n[bandit]\nexclude_dirs = tests\nskips = B101, B601\n```\n\n#### **Safety** - V\u00e9rification des d\u00e9pendances\n\n```bash\n# Installer Safety\npip install safety\n\n# V\u00e9rifier les vuln\u00e9rabilit\u00e9s (commande d\u00e9pr\u00e9ci\u00e9e)\nsafety check\n\n# V\u00e9rifier avec la nouvelle commande (recommand\u00e9)\n# Note: N\u00e9cessite un compte Safety CLI (gratuit)\nsafety scan\n\n# Premi\u00e8re utilisation: Safety demandera de cr\u00e9er un compte\n# Suivez les instructions pour vous enregistrer\n```\n\n### Workflow complet de d\u00e9veloppement\n\n#### **Script de pr\u00e9-commit**\n\n```bash\n#!/bin/bash\n# .git/hooks/pre-commit\n\necho \"\ud83d\udd0d V\u00e9rification du code...\"\n\n# Formater le code\nblack mailopt/ tests/\nisort mailopt/ tests/\n\n# Linter\nflake8 mailopt/ tests/\npylint mailopt/ --score=8.0\n\n# V\u00e9rifier les types\nmypy mailopt/ --ignore-missing-imports\n\n# Tests rapides\npytest tests/ -x --tb=short\n\necho \"\u2705 Pr\u00e9-commit termin\u00e9 avec succ\u00e8s!\"\n```\n\n#### **Script de CI complet**\n\n```bash\n#!/bin/bash\n# scripts/ci.sh\n\nset -e\n\necho \"\ud83d\ude80 D\u00e9marrage du CI...\"\n\n# Installer les d\u00e9pendances\npip install -e \".[dev,test]\"\n\n# Formater et v\u00e9rifier\nblack --check mailopt/ tests/\nisort --check-only mailopt/ tests/\n\n# Linter\nflake8 mailopt/ tests/\npylint mailopt/ --score=8.0\n\n# V\u00e9rifier les types\nmypy mailopt/ --ignore-missing-imports\n\n# Tests avec couverture\npytest --cov=mailopt --cov-report=xml tests/\n\n# S\u00e9curit\u00e9\nbandit -r mailopt/\nsafety check\n\n# Build\npython -m build\ntwine check dist/*\n\necho \"\u2705 CI termin\u00e9 avec succ\u00e8s!\"\n```\n\n### Configuration des outils\n\n#### **pyproject.toml** - Configuration centralis\u00e9e\n\n```toml\n[build-system]\nrequires = [\"setuptools>=45\", \"wheel\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[tool.black]\nline-length = 88\ntarget-version = ['py310']\n\n[tool.isort]\nprofile = \"black\"\nline_length = 88\n\n[tool.mypy]\npython_version = \"3.10\"\nwarn_return_any = true\ndisallow_untyped_defs = true\n\n[tool.pytest.ini_options]\ntestpaths = [\"tests\"]\npython_files = [\"test_*.py\"]\naddopts = \"-v --tb=short\"\nmarkers = [\n    \"slow: marks tests as slow\",\n    \"integration: marks tests as integration tests\",\n]\n```\n\n#### **.pre-commit-config.yaml** - Hooks automatiques\n\n```yaml\nrepos:\n  - repo: https://github.com/psf/black\n    rev: 23.3.0\n    hooks:\n      - id: black\n        language_version: python3.10\n\n  - repo: https://github.com/pycqa/isort\n    rev: 5.12.0\n    hooks:\n      - id: isort\n\n  - repo: https://github.com/pycqa/flake8\n    rev: 6.0.0\n    hooks:\n      - id: flake8\n\n  - repo: https://github.com/pre-commit/mirrors-mypy\n    rev: v1.3.0\n    hooks:\n      - id: mypy\n        additional_dependencies: [types-requests]\n```\n\n## CI/CD\n\n### Workflow GitHub Actions\n\n```yaml\n# .github/workflows/ci.yml\nname: CI\n\non: [push, pull_request]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        python-version: [3.10, 3.11, 3.12]\n\n    steps:\n      - uses: actions/checkout@v3\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v4\n        with:\n          python-version: ${{ matrix.python-version }}\n      - name: Install dependencies\n        run: |\n          pip install -e .\n          pip install pytest pytest-cov flake8 pylint\n      - name: Run tests\n        run: pytest --cov=mailopt tests/\n      - name: Run linter\n        run: |\n          flake8 mailopt/ tests/\n          pylint mailopt/\n```\n\n### Pr\u00e9-commit hook\n\n```bash\n#!/bin/bash\n# .git/hooks/pre-commit\n\n# V\u00e9rifier les noms de fichiers\nmailopt lint-names . --fix\n\n# Trouver les fichiers orphelins\nmailopt find-orphans ./assets --dry-run\n\n# Tests rapides\npytest tests/ -x\n```\n\n## Workflow Git & Contribuer\n\n### Branche feature\n\n```bash\n# Cr\u00e9er une branche feature\ngit checkout -b feat/amazing-feature\n\n# Commits atomiques\ngit commit -m \"feat: add amazing feature\"\ngit commit -m \"test: add tests for amazing feature\"\ngit commit -m \"docs: update documentation for amazing feature\"\n```\n\n### Mod\u00e8le de message de commit (Conventional Commits)\n\n```\n<type>[optional scope]: <description>\n\n[optional body]\n\n[optional footer(s)]\n```\n\n**Types :**\n\n- `feat` : Nouvelle fonctionnalit\u00e9\n- `fix` : Correction de bug\n- `docs` : Documentation\n- `style` : Formatage\n- `refactor` : Refactoring\n- `test` : Tests\n- `chore` : Maintenance\n\n**Exemples :**\n\n```bash\ngit commit -m \"feat(inline): add CSS minification option\"\ngit commit -m \"fix(check-images): handle case-sensitive file systems\"\ngit commit -m \"docs: update installation instructions\"\n```\n\n## Roadmap & Perspectives\n\n### Fonctionnalit\u00e9s \u00e0 venir\n\n- **Int\u00e9gration Litmus avanc\u00e9e** : Tests automatis\u00e9s sur tous les clients email\n- **Merge-tags avanc\u00e9** : Support de templates complexes et conditions\n- **API REST** : Interface web pour les \u00e9quipes non-techniques\n- **Int\u00e9gration CI/CD** : Plugins pour GitHub Actions, GitLab CI\n- **Support multi-langues** : Interface en fran\u00e7ais, anglais, espagnol\n- **Mode watch** : Surveillance en temps r\u00e9el des fichiers\n- **Rapports avanc\u00e9s** : Graphiques et m\u00e9triques d\u00e9taill\u00e9es\n\n### Appel \u00e0 contributions\n\nBien que le projet soit actuellement maintenu par un seul d\u00e9veloppeur, nous encourageons les contributions de la communaut\u00e9 email development. Les domaines prioritaires :\n\n- Tests de compatibilit\u00e9 email\n- Optimisation d'images\n- Accessibilit\u00e9\n- Documentation\n- Int\u00e9grations tierces\n\n## Licence\n\nCe projet est sous licence MIT - voir le fichier [LICENSE](LICENSE) pour les d\u00e9tails.\n\n**MIT License** - Licence permissive permettant :\n\n- Usage commercial\n- Modification\n- Distribution\n- Usage priv\u00e9\n\nAvec protection de responsabilit\u00e9 pour les auteurs.\n\n## Contacts & Liens\n\n### Issues & Discussions\n\n- **Issues** : [GitHub Issues](https://github.com/your-username/mailopt/issues)\n- **Discussions** : [GitHub Discussions](https://github.com/your-username/mailopt/discussions)\n- **Wiki** : [Documentation d\u00e9taill\u00e9e](https://github.com/your-username/mailopt/wiki)\n\n### Mainteneurs\n\n- **D\u00e9veloppeur principal** : [@your-username](https://github.com/your-username)\n\n### Liens utiles\n\n- **PyPI** : [pypi.org/project/mailopt](https://pypi.org/project/mailopt/)\n- **Documentation** : [mailopt.readthedocs.io](https://mailopt.readthedocs.io/)\n- **Changelog** : [CHANGELOG.md](CHANGELOG.md)\n\n---\n\n**Fait avec \u2764\ufe0f pour la communaut\u00e9 email development**\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "CLI Python pour automatiser et optimiser les workflows email/front-end",
    "version": "0.1.0",
    "project_urls": {
        "Bug Reports": "https://github.com/vml-marketing-mail/mailopt/issues",
        "Documentation": "https://github.com/vml-marketing-mail/mailopt#readme",
        "Homepage": "https://github.com/vml-marketing-mail/mailopt",
        "Source": "https://github.com/vml-marketing-mail/mailopt"
    },
    "split_keywords": [
        "email",
        " cli",
        " automation",
        " optimization",
        " frontend",
        " workflow"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "78422be7ea3a259516f95bad188d060f18d81be93ea59d8b858b1e173836a4fd",
                "md5": "ef4a7d3efc771fd1eacfd33001380591",
                "sha256": "0e38fd5313dc5d5f488c3f018f9d4b25f86621f7d35ec75e087998743cd41463"
            },
            "downloads": -1,
            "filename": "mailopt-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ef4a7d3efc771fd1eacfd33001380591",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 16033,
            "upload_time": "2025-07-22T17:39:42",
            "upload_time_iso_8601": "2025-07-22T17:39:42.522056Z",
            "url": "https://files.pythonhosted.org/packages/78/42/2be7ea3a259516f95bad188d060f18d81be93ea59d8b858b1e173836a4fd/mailopt-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5281a3fae0ff328a4cf4c1634c10c65c3f42f0932177270dbeba40d26ca4d960",
                "md5": "4856380727501d58d29a34f5a6be125e",
                "sha256": "0fb11701f42402a646acbeff2fe6125b75143f661847e400b58abc5cf6c37e3b"
            },
            "downloads": -1,
            "filename": "mailopt-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "4856380727501d58d29a34f5a6be125e",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 16005,
            "upload_time": "2025-07-22T17:39:43",
            "upload_time_iso_8601": "2025-07-22T17:39:43.920043Z",
            "url": "https://files.pythonhosted.org/packages/52/81/a3fae0ff328a4cf4c1634c10c65c3f42f0932177270dbeba40d26ca4d960/mailopt-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-22 17:39:43",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "vml-marketing-mail",
    "github_project": "mailopt",
    "github_not_found": true,
    "lcname": "mailopt"
}
        
Elapsed time: 1.33394s