diff --git a/requirements.txt b/requirements.txt index 3e5e8898..630a6e7a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -28,7 +28,8 @@ pycrypto==2.6.1 # via paramiko pyflakes==0.8.1 # via flake8 python-dateutil==2.4.2 # via arrow redis==2.10.3 -rq==0.5.3 +-e git+https://github.com/vy-labs/rq.git@v0.8.1#egg=rq six==1.9.0 # via python-dateutil werkzeug==0.10.4 # via flask wheel==0.24.0 +python-dotenv==0.6.4 diff --git a/rq_dashboard/__init__.py b/rq_dashboard/__init__.py index ced27f48..57a4dd88 100644 --- a/rq_dashboard/__init__.py +++ b/rq_dashboard/__init__.py @@ -1,3 +1,12 @@ +from os.path import exists + +from dotenv import load_dotenv + +dotenv_path = '/etc/environment' +if exists(dotenv_path): + print("loading environment variables from /etc/environment file..") + load_dotenv(dotenv_path) + # flake8: noqa from . import default_settings from .web import blueprint diff --git a/rq_dashboard/cli.py b/rq_dashboard/cli.py index 2145e8da..b593888c 100755 --- a/rq_dashboard/cli.py +++ b/rq_dashboard/cli.py @@ -2,9 +2,11 @@ import importlib import os +import sys import click from flask import Flask, Response, request +from rq.utils import import_attribute from . import default_settings from .version import VERSION @@ -90,11 +92,25 @@ def make_flask_app(config, username, password, url_prefix): @click.option( '--interval', default=None, type=int, help='Refresh interval in ms') +@click.option('--path', default='.', + help='Specify the import path.') +@click.option('--worker-class', '-w', + envvar='RQ_WORKER_CLASS', + default=default_settings.DEFAULT_WORKER_CLASS, + help='RQ Worker class to use') +@click.option('--job-class', '-j', + envvar='RQ_JOB_CLASS', + default=default_settings.DEFAULT_JOB_CLASS, + help='RQ Job class to use') +@click.option('--queue-class', + envvar='RQ_QUEUE_CLASS', + default=default_settings.DEFAULT_QUEUE_CLASS, + help='RQ Queue class to use') def run( bind, port, url_prefix, username, password, config, redis_host, redis_port, redis_password, redis_database, redis_url, - interval): + interval, path, worker_class, job_class, queue_class): """Run the RQ Dashboard Flask server. All configuration can be set on the command line or through environment @@ -106,6 +122,9 @@ def run( RQ_DASHBOARD_SETTINGS environment variable. """ + if path: + sys.path = path.split(':') + sys.path + click.echo('RQ Dashboard version {0}'.format(VERSION)) app = make_flask_app(config, username, password, url_prefix) if redis_url: @@ -120,6 +139,12 @@ def run( app.config['REDIS_DB'] = redis_database if interval: app.config['RQ_POLL_INTERVAL'] = interval + if worker_class: + app.config['WORKER_CLASS'] = import_attribute(worker_class) + if job_class: + app.config['JOB_CLASS'] = import_attribute(job_class) + if queue_class: + app.config['QUEUE_CLASS'] = import_attribute(queue_class) app.run(host=bind, port=port) diff --git a/rq_dashboard/default_settings.py b/rq_dashboard/default_settings.py index cc52db67..1c0c2db5 100644 --- a/rq_dashboard/default_settings.py +++ b/rq_dashboard/default_settings.py @@ -17,3 +17,7 @@ RQ_POLL_INTERVAL = 2500 #: Web interface poll period for updates in ms DEBUG = False + +DEFAULT_JOB_CLASS = 'rq.job.Job' +DEFAULT_QUEUE_CLASS = 'rq.Queue' +DEFAULT_WORKER_CLASS = 'rq.Worker' diff --git a/rq_dashboard/web.py b/rq_dashboard/web.py index 14512fff..2bb343c3 100644 --- a/rq_dashboard/web.py +++ b/rq_dashboard/web.py @@ -22,9 +22,9 @@ import arrow from flask import Blueprint, current_app, render_template, url_for from redis import Redis, from_url -from rq import (Queue, Worker, cancel_job, get_failed_queue, pop_connection, +from rq import (cancel_job, get_failed_queue, pop_connection, push_connection, requeue_job) - +# Queue, Worker blueprint = Blueprint( 'rq_dashboard', __name__, @@ -123,6 +123,8 @@ def pagination_window(total_items, cur_page, per_page=5, window_size=10): @blueprint.route('/', defaults={'page': '1'}) @blueprint.route('//') def overview(queue_name, page): + Queue = current_app.config.get('QUEUE_CLASS') + Worker = current_app.config.get('WORKER_CLASS') if queue_name is None: # Show the failed queue by default if it contains any jobs failed = Queue('failed') @@ -171,6 +173,7 @@ def requeue_all(): @blueprint.route('/queue//empty', methods=['POST']) @jsonify def empty_queue(queue_name): + Queue = current_app.config.get('QUEUE_CLASS') q = Queue(queue_name) q.empty() return dict(status='OK') @@ -179,6 +182,7 @@ def empty_queue(queue_name): @blueprint.route('/queue//compact', methods=['POST']) @jsonify def compact_queue(queue_name): + Queue = current_app.config.get('QUEUE_CLASS') q = Queue(queue_name) q.compact() return dict(status='OK') @@ -187,6 +191,7 @@ def compact_queue(queue_name): @blueprint.route('/queues.json') @jsonify def list_queues(): + Queue = current_app.config.get('QUEUE_CLASS') queues = serialize_queues(sorted(Queue.all())) return dict(queues=queues) @@ -194,6 +199,7 @@ def list_queues(): @blueprint.route('/jobs//.json') @jsonify def list_jobs(queue_name, page): + Queue = current_app.config.get('QUEUE_CLASS') current_page = int(page) queue = Queue(queue_name) per_page = 5 @@ -235,6 +241,8 @@ def list_workers(): def serialize_queue_names(worker): return [q.name for q in worker.queues] + Worker = current_app.config.get('WORKER_CLASS') + workers = [ dict( name=worker.name,