A Flask-based web application for scheduling and managing recurring tasks. This application provides a user-friendly interface to configure, monitor, and execute various job modules on scheduled intervals.
- 🔄 Flexible Scheduling: Support for interval-based (minutes, hours, days, weeks) and cron-based scheduling
- 🌐 Web Interface: Clean, responsive Bootstrap-based UI for job management
- 📦 Modular Architecture: Dynamically discovers and loads job modules
- ⚡ Manual Triggers: Run jobs immediately via the web interface
- 📊 Status Monitoring: Track job execution status, success/failure, and timing
- 💾 Persistent Configuration: Jobs are saved to JSON configuration file
- 🐳 Docker Support: Containerized deployment ready
- 🔒 Safety Features: Built-in retry mechanisms and verification for critical operations
IMAP-to-IMAP email migration tool with advanced features:
- Copies/moves emails between IMAP mailboxes
- Preserves flags and timestamps
- Deduplication using Message-ID
- Safety mode with verification before deletion
- Marks migrated emails as unread in destination
- Retry mechanisms with exponential backoff
IMAP-to-Gmail migration tool using Gmail API for optimal performance:
- Reads emails from any IMAP server
- Imports to Gmail using Gmail API (not IMAP)
- OAuth2 authentication for enhanced security
- Better metadata preservation than IMAP
- Native Gmail label support
- Deduplication using Message-ID
- Safety mode with verification before deletion
- Retry mechanisms with exponential backoff
When to use which:
- Use email_movefor IMAP-to-IMAP migrations (non-Gmail destinations)
- Use imap_to_gmailfor migrating to Gmail/Google Workspace (better performance)
- 
Clone the repository git clone <repository-url> cd regular_tasks 
- 
Install dependencies pip install -r requirements.txt 
- 
Start the application python main.py 
- 
Access the web interface Open your browser and navigate to http://localhost:8000
The project automatically builds Docker images via GitHub Actions and publishes them to GitHub Container Registry.
- 
Pull the latest image docker pull ghcr.io/OWNER/REPOSITORY:latest 
- 
Run the container docker run -d \ --name regular-tasks \ -p 8000:8000 \ -v $(pwd)/data:/app/data \ -v $(pwd)/logs:/app/logs \ ghcr.io/jvsoest/regular_tasks:latest 
- 
Build the Docker image docker build -t regular-tasks .
- 
Run the container docker run -d \ --name regular-tasks \ -p 8000:8000 \ -v $(pwd)/data:/app/data \ -v $(pwd)/logs:/app/logs \ regular-tasks 
Create a docker-compose.yml file:
version: '3.8'
services:
  regular-tasks:
    image: ghcr.io/OWNER/REPOSITORY:latest  # or build: . for local builds
    ports:
      - "8000:8000"
    volumes:
      - ./data:/app/data
      - ./logs:/app/logs
      - ./jobs_config.json:/app/jobs_config.json
    environment:
      - FLASK_ENV=production
    restart: unless-stoppedRun with:
docker-compose up -d- 
Create a module directory with a run.pyfile:your_module/ ├── run.py └── config.yaml
- 
Implement required functions in run.py:def load_config(path: str): # Load configuration from file pass def migrate(cfg): # Main execution function pass # OR alternatively: def main(): # Entry point using sys.argv for config file pass 
- 
The module will be automatically discovered by the application 
Create a YAML configuration file for the email_move module:
source:
  host: imap.source.com
  port: 993
  username: source@example.com
  password: source_password
  ssl: true
  mailbox: INBOX
dest:
  host: imap.destination.com
  port: 993
  username: dest@example.com
  password: dest_password
  ssl: true
  mailbox: INBOX
options:
  batch_size: 200
  dedupe_by: message_id
  create_dest_mailbox: true
  search_query: ALL
  delete_after_copy: false
  safety_mode: true
  verify_strategy: message_id
  max_retries: 3
  retry_backoff_sec: 2.0For detailed setup instructions, see imap_to_gmail/USAGE.md.
Prerequisites:
- Install dependencies: pip install google-auth-oauthlib google-auth-httplib2 google-api-python-client
- Set up OAuth2 credentials from Google Cloud Console
- Download credentials.jsonfrom Google Cloud Console
Quick Start:
cd imap_to_gmail
cp config.yaml.template config.yaml
# Edit config.yaml with your IMAP server details
python quickstart.py  # Interactive setup and first runConfiguration Example:
source:
  host: imap.source.com
  port: 993
  username: source@example.com
  password: source_password
  ssl: true
  mailbox: INBOX
gmail:
  credentials_file: credentials.json
  token_file: token.json
  user_id: me
options:
  search_query: ALL
  batch_size: 100
  dedupe_by: message_id
  delete_after_import: false
  safety_mode: true
  gmail_labels: []
  mark_as_unread: true
  max_retries: 3
  retry_backoff_sec: 2.0- GET /- Main dashboard
- GET /add_job- Add new job form
- POST /add_job- Create new job
- GET /toggle_job/<job_id>- Enable/disable job
- GET /run_job/<job_id>- Manually trigger job
- GET /remove_job/<job_id>- Remove job
- GET /logs/<job_id>- View job logs
- GET /api/jobs- JSON API for job status
| Variable | Description | Default | 
|---|---|---|
| FLASK_ENV | Flask environment | development | 
| FLASK_SECRET_KEY | Secret key for Flask sessions | Auto-generated | 
| SCHEDULER_PORT | Port to run the application | 8000 | 
regular_tasks/
├── main.py                 # Main Flask application
├── requirements.txt        # Python dependencies
├── Dockerfile             # Container configuration
├── docker-compose.yml     # Docker Compose setup
├── jobs_config.json       # Job configurations (auto-created)
├── templates/             # HTML templates
│   ├── base.html
│   ├── index.html
│   ├── add_job.html
│   └── logs.html
├── email_move/           # IMAP-to-IMAP migration module
│   ├── run.py
│   └── config.yaml
├── imap_to_gmail/        # IMAP-to-Gmail migration module
│   ├── run.py
│   ├── config.yaml
│   ├── credentials.json  # OAuth2 credentials (download from Google)
│   ├── token.json        # OAuth2 token (auto-generated)
│   ├── quickstart.py     # Interactive setup script
│   ├── test_setup.py     # Configuration test script
│   ├── integration.py    # Scheduler integration example
│   ├── README.md         # Module documentation
│   └── USAGE.md          # Detailed usage guide
├── log/                  # Job execution logs
└── data/                 # Persistent data directory
- 
Module Import Errors - Ensure your module has a run.pyfile
- Check that required functions (mainormigrate) are implemented
 
- Ensure your module has a 
- 
Permission Errors in Docker - Ensure proper volume mounting
- Check file permissions on mounted directories
 
- 
Job Execution Failures - Check job logs in the web interface
- Verify configuration file syntax
- Ensure all required dependencies are installed
 
- Application logs are printed to console
- Individual job execution logs are stored persistently in the /logdirectory
- Access logs via the web interface: /logs/<job_id>
- Automatic log rotation prevents unlimited disk usage
The application includes configurable log rotation to manage disk space:
Environment Variables:
- LOG_ROTATION_ENABLED- Enable/disable rotation (default:- true)
- LOG_ROTATION_DAYS- Keep logs for N days (default:- 7)
- LOG_ROTATION_COUNT- Max files per job (default:- 10)
Rotation Behavior:
- Files older than LOG_ROTATION_DAYSare automatically deleted
- Each job keeps maximum LOG_ROTATION_COUNTmost recent files
- Rotation runs after each job execution and at startup
- Manual rotation available via admin interface at /admin/logs
Examples:
# Keep logs for 30 days, max 5 files per job
export LOG_ROTATION_DAYS=30
export LOG_ROTATION_COUNT=5
# Disable rotation completely
export LOG_ROTATION_ENABLED=false
# Run with custom settings
LOG_ROTATION_DAYS=14 python main.py- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
- Implement either main()ormigrate(cfg)function
- Use load_config(path)for configuration loading
- Handle errors gracefully
- Provide informative logging
- Follow Python best practices
- Change the default Flask secret key in production
- Use environment variables for sensitive configuration
- Implement proper authentication if exposing to internet
- Regularly update dependencies
- Use HTTPS in production environments
This project is open source. Please check the LICENSE file for details.
Contributions are welcome! Please read the development guidelines and submit pull requests for any improvements.
For issues and questions:
- Check the troubleshooting section
- Review existing issues in the repository
- Create a new issue with detailed information about the problem