コード例 #1
0
ファイル: eg_scheduler.py プロジェクト: sohcalvin/ref
def setupInterval() :
    from apscheduler.schedulers.background import BackgroundScheduler


    scheduler = BackgroundScheduler()
    # scheduler.add_job(printIt,"interval", seconds=3, coalesce=True )
    scheduler.add_cron_job(printIt, day_of_week='mon-fri', hour=5, minute=30)
    scheduler.start()
    print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
    try:
        # This is here to simulate application activity (which keeps the main thread alive).
        while True:  time.sleep(2)
    except (KeyboardInterrupt, SystemExit):
        # Not strictly necessary if daemonic mode is enabled but should be done if possible
        sched.shutdown()

    return scheduler
コード例 #2
0
ファイル: base.py プロジェクト: jmaniac/Flask-Report
class FlaskReport(object):
    def __init__(self, db, model_map, app, blueprint=None, extra_params=None, table_label_map=None, mail=None):
        self.db = db
        self.app = app
        host = blueprint or app
        self.conf_dir = app.config.get("REPORT_DIR", "report_conf")
        self.report_dir = os.path.join(self.conf_dir, "reports")
        self.notification_dir = os.path.join(self.conf_dir, "notifications")
        self.data_set_dir = os.path.join(self.conf_dir, "data_sets")
        self.model_map = model_map  # model name -> model
        self.table_label_map = table_label_map or {}
        self.table_map = dict((model.__tablename__, model) for model in model_map.values())  # table name -> model
        if not os.path.exists(self.conf_dir):
            os.makedirs(self.conf_dir)
        if not os.path.exists(self.report_dir):
            os.makedirs(self.report_dir)
        if not os.path.exists(self.data_set_dir):
            os.makedirs(self.data_set_dir)

        host.route("/report-list/")(self.report_list)
        host.route("/new-report/", methods=['POST'])(self.new_report)
        host.route("/graphs/report/<int:id_>")(self.report_graphs)
        host.route("/report/<int:id_>", methods=['GET', 'POST'])(self.report)
        host.route("/report_csv/<int:id_>")(self.report_csv)
        host.route("/report_pdf/<int:id_>")(self.report_pdf)
        host.route("/report_txt/<int:id_>")(self.report_txt)
        host.route("/drill-down-detail/<int:report_id>/<int:col_id>")(self.drill_down_detail)

        host.route("/data-sets/")(self.data_set_list)
        host.route("/data-set/<int:id_>")(self.data_set)
        host.route("/notification-list")(self.notification_list)
        host.route("/notification/", methods=['GET', 'POST'])(self.notification)
        host.route("/notification/<int:id_>", methods=['GET', 'POST'])(self.notification)
        host.route("/push_notification/<int:id_>", methods=['POST'])(self.push_notification)
        host.route("/start_notification/<int:id_>", methods=['GET'])(self.start_notification)
        host.route("/stop_notification/<int:id_>", methods=['GET'])(self.stop_notification)
        host.route("/schedule-list")(self.get_schedules)

        from flask import Blueprint
        # register it for using the templates of data browser
        self.blueprint = Blueprint("report____", __name__,
                                   static_folder="static",
                                   template_folder="templates")
        app.register_blueprint(self.blueprint, url_prefix="/__report__")
        self.extra_params = extra_params or {'report': lambda id_: {},
                                             'report_list': lambda: {},
                                             'data_set': lambda id_: {},
                                             'data_sets': lambda: {},
                                             'notification-list': lambda: {},
                                             'notification': lambda id_: {}}

        @app.template_filter("dpprint")
        def dict_pretty_print(value):
            if not isinstance(value, list):
                value = [value]
            s = "{"
            for val in value:
                idx = 0
                for k, v in val.items():
                    idx += 1
                    s += "%s:%s" % (k, v)
                    if idx != len(val):
                        s += ","
            s += "}"
            return s

        self.mail = mail or Mail(self.app)
        self.sched = BackgroundScheduler()
        if app.config.get('FLASK_REPORT_SEND_NOTIFICATION'):
            self.sched.start()

            with app.test_request_context():
                for notification in get_all_notifications(self):
                    if notification.enabled:
                        self.start_notification(notification.id_)


    def try_view_report(self):
        pass

    def try_edit_data_set(self):
        pass

    def try_edit_notification(self):
        pass

    def report_graphs(self, id_):
        report = Report(self, id_)
        return render_template("report____/graphs.html", url=request.args.get("url"), bar_charts=report.bar_charts,
                               name=report.name, pie_charts=report.pie_charts)

    def data_set_list(self):
        self.try_edit_data_set()
        data_sets = [DataSet(self, int(dir_name)) for dir_name in os.listdir(self.data_set_dir) if
                     dir_name.isdigit() and dir_name != '0']
        params = dict(data_sets=data_sets)
        extra_params = self.extra_params.get("data_sets")
        if extra_params:
            if isinstance(extra_params, types.FunctionType):
                extra_params = extra_params()
            params.update(extra_params)
        return render_template("report____/data-sets.html", **params)

    def data_set(self, id_):
        self.try_edit_data_set()
        data_set = DataSet(self, id_)
        SQL_html = highlight(query_to_sql(data_set.query), SqlLexer(), HtmlFormatter())
        params = dict(data_set=data_set, SQL=SQL_html)
        extra_params = self.extra_params.get('data_set')
        if extra_params:
            if isinstance(extra_params, types.FunctionType):
                extra_params = extra_params(id_)
            params.update(extra_params)
        return render_template("report____/data-set.html", **params)

    def _get_report_list(self):
        return [Report(self, int(dir_name)) for dir_name in os.listdir(self.report_dir) if
                dir_name.isdigit() and dir_name != '0']

    def report_list(self):
        self.try_view_report()
        # directory 0 is reserved for special purpose
        reports = self._get_report_list()
        params = dict(reports=reports)
        extra_params = self.extra_params.get('report_list')
        if extra_params:
            if isinstance(extra_params, types.FunctionType):
                extra_params = extra_params()
            params.update(extra_params)
        return render_template('report____/report-list.html', **params)

    def report(self, id_=None):
        self.try_view_report()
        if id_ is not None:
            report = Report(self, id_)

            html_report = report.html_template.render(report=report)
            code = report.read_literal_filter_condition()

            SQL_html = highlight(query_to_sql(report.query), SqlLexer(), HtmlFormatter())
            params = dict(report=report, html_report=html_report, SQL=SQL_html)
            if code is not None:
                customized_filter_condition = highlight(code, PythonLexer(), HtmlFormatter())
                params['customized_filter_condition'] = customized_filter_condition
            extra_params = self.extra_params.get("report")
            if extra_params:
                if isinstance(extra_params, types.FunctionType):
                    extra_params = extra_params(id_)
                params.update(extra_params)
            return render_template("report____/report.html", **params)

    def _write_report(self, to_dir, **kwargs):
        import yaml

        kwargs.setdefault("name", "temp")
        kwargs.setdefault("description", "temp")
        import datetime

        kwargs["create_time"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        file_name = os.path.join(to_dir, "meta.yaml")
        if os.path.isfile(file_name):
            new_file_name = os.path.join(to_dir, "meta.yaml~")
            if os.path.isfile(new_file_name):
                os.unlink(new_file_name)
            os.rename(file_name, new_file_name)
        with file(file_name, "w") as f:
            yaml.safe_dump(kwargs, allow_unicode=True, stream=f)

    def _get_report(self, id_, ReportClass):
        from flask.ext.report.report_templates import BaseReport

        assert issubclass(ReportClass, BaseReport)
        data = Report(self, id_)
        if not data.data:
            raise ValueError
        report = ReportClass(queryset=data.data, columns=data.columns, report_name=data.name,
                             sum_columns=data.sum_columns, avg_columns=data.avg_columns)
        return report

    def _get_report_value(self, id_, ReportClass, ReportGenerator, first_row_with_column_names=False):
        from flask.ext.report.report_templates import BaseReport

        assert issubclass(ReportClass, BaseReport)

        from geraldo.generators import base

        assert issubclass(ReportGenerator, base.ReportGenerator)
        try:
            from cStringIO import StringIO
        except ImportError:
            from StringIO import StringIO
        return_fileobj = StringIO()
        from flask.ext.report.writer import UnicodeWriter

        report = self._get_report(id_, ReportClass)

        report.generate_by(ReportGenerator, filename=return_fileobj, writer=UnicodeWriter(return_fileobj),
                           first_row_with_column_names=first_row_with_column_names)
        return return_fileobj

    def _get_report_class(self, id_, default=None):
        if default is None:
            raise ValueError
        filter_def_file = os.path.join(self.report_dir, str(id_), "report_templates.py")
        if not os.path.exists(filter_def_file):
            filter_def_file = os.path.join(self.report_dir, "0", "report_templates.py")
        if os.path.exists(filter_def_file):
            from import_file import import_file

            lib = import_file(filter_def_file)
            return getattr(lib, default.__name__, default)
        return default

    def report_csv(self, id_):
        from geraldo.generators import CSVGenerator
        from flask.ext.report.report_templates import CSVReport

        try:
            return_fileobj = self._get_report_value(id_, self._get_report_class(id_, CSVReport), CSVGenerator, True)
        except ValueError:
            return render_template("report____/error.html", error=u"没有该报告", message=u"无法导出空报告"), 403
        from flask import Response

        response = Response(return_fileobj.getvalue(), mimetype="text/csv")
        response.headers["Content-disposition"] = "attachment; filename={}.csv".format(str(id_))
        return response

    def report_pdf(self, id_):
        from flask.ext.report.report_templates import PDFReport
        from geraldo.generators import PDFGenerator

        try:
            return_fileobj = self._get_report_value(id_, self._get_report_class(id_, PDFReport), PDFGenerator, True)
        except ValueError:
            return render_template("report____/error.html", error=u"没有该报告", message=u"无法导出空报告"), 403
        from flask import Response

        response = Response(return_fileobj.getvalue(), mimetype="application/pdf")
        response.headers["Content-disposition"] = "attachment; filename={}.pdf".format(str(id_))
        return response

    def report_txt(self, id_):
        from flask.ext.report.report_templates import TxtReport

        from geraldo.generators import TextGenerator

        try:
            return_fileobj = self._get_report_value(id_, self._get_report_class(id_, TxtReport), TextGenerator, True)
        except ValueError:
            return render_template("report____/error.html", error=u"没有该报告", message=u"无法导出空报告"), 403
        from flask import Response

        response = Response(return_fileobj.getvalue(), mimetype="text/plan")
        response.headers["Content-disposition"] = "attachment; filename={}.txt".format(str(id_))
        return response

    def get_model_label(self, table):
        return self.table_label_map.get(table.name) or self.table_map[table.name].__name__

    def drill_down_detail(self, report_id, col_id):
        filters = request.args
        report = Report(self, report_id)
        col = report.data_set.columns[col_id]['expr']
        col = get_column_operated(getattr(col, 'element', col))
        model_name = self.get_model_label(col.table)
        items = report.get_drill_down_detail(col_id, **filters)
        return report.get_drill_down_detail_template(col_id).render(items=items,
                                                                    key=col.key,
                                                                    model_name=model_name,
                                                                    report=report)

    def notification_list(self):
        notifications = [Notification(self, int(dir_name)) for dir_name in os.listdir(self.notification_dir) if
                         dir_name.isdigit() and dir_name != '0']
        params = dict(notification_list=notifications)
        extra_params = self.extra_params.get("notification_list")
        if extra_params:
            if isinstance(extra_params, types.FunctionType):
                extra_params = extra_params()
            params.update(extra_params)
        return render_template("report____/notification-list.html", **params)

    def notification(self, id_=None):
        self.try_edit_notification()

        def _write(form, id_):
            kwargs = dict(name=form["name"], senders=form.getlist("sender"),
                          report_ids=form.getlist("report_ids", type=int), description=form["description"],
                          subject=form["subject"], crontab=form["crontab"],
                          enabled=form.get("enabled", type=bool, default=False))
            dump_yaml(os.path.join(self.notification_dir, str(id_), 'meta.yaml'), **kwargs)

        if id_ is not None:
            notification = Notification(self, id_)

            if request.method == "POST":
                if request.form.get('action') == _('Enable'):
                    self.start_notification(id_)
                elif request.form.get("action") == _("Disable"):
                    self.stop_notification(id_)  # any change will incur disable
                else:
                    _write(request.form, id_)
                flash(_("Update Successful!"))
                return redirect(url_for(".notification", id_=id_, _method="GET"))
            else:
                params = dict(notification=notification,
                              report_list=self._get_report_list())
                extra_params = self.extra_params.get("notification")
                if extra_params:
                    if isinstance(extra_params, types.FunctionType):
                        extra_params = extra_params(id_)
                    params.update(extra_params)
                return render_template("report____/notification.html", **params)
        else:
            if request.method == "POST":
                id_ = max([int(dir_name) for dir_name in os.listdir(self.notification_dir) if
                           dir_name.isdigit() and dir_name != '0']) + 1
                new_dir = os.path.join(self.notification_dir, str(id_))
                if not os.path.exists(new_dir):
                    os.mkdir(new_dir)
                _write(request.form, id_)
                flash(_("Save Successful!"))
                return redirect(url_for(".notification", id_=id_))
            else:
                params = dict(report_list=self._get_report_list())
                extra_params = self.extra_params.get("notification")
                if extra_params:
                    if isinstance(extra_params, types.FunctionType):
                        extra_params = extra_params()
                    params.update(extra_params)
                return render_template("report____/notification.html", **params)

    def push_notification(self, id_):
        to = request.args.get('to')
        notification = Notification(self, id_)
        if not to:
            senders = notification.senders
        else:
            senders = [to]

        for sender in senders:
            if sender not in notification.senders in senders:
                return _('notification %(id_)s are not allowed to send to %(to)s', id_=id_, to=sender), 403
        html = notification.template.render(notification=notification)
        msg = Message(subject=notification.subject,
                      html=html,
                      sender="*****@*****.**",
                      recipients=senders)
        self.mail.send(msg)
        return 'ok'

    def start_notification(self, id_):
        notification = Notification(self, id_)

        def _closure(environ):
            def _push_notification():
                with self.app.request_context(environ):
                    self.push_notification(id_)

            return _push_notification

        job = self.sched.add_cron_job(_closure(request.environ), name='flask_report_notification' + str(id_),
                                      **notification.crontab._asdict())
        notification.enabled = True
        notification.dump()
        return 'ok'

    def stop_notification(self, id_):
        jobs = self.sched.get_jobs()
        for job in jobs:
            if job.name == 'flask_report_notification' + str(id_):
                notification = Notification(self, id_)
                notification.enabled = False
                notification.dump()
                self.sched.unschedule_job(job)
            return 'ok'
        else:
            return 'unknown notifiaction:' + str(id_), 404

    def get_schedules(self):
        return json.dumps([str(job) for job in self.sched.get_jobs()])

    def new_report(self):

        form = _ReportForm(self, request.form)

        if form.validate():
            def parse_filters(filters):
                result = {}
                for current in filters:
                    if current["col"] not in result:
                        result[current["col"]] = {'operator': current["op"], 'value': current["val"],
                                                  'proxy': current['proxy']}
                    else:
                        val = result[current["col"]]
                        if not isinstance(val, list):
                            val = [val]
                        val.append({'operator': current["op"], 'value': current["val"], 'proxy': current['proxy']})
                        result[current["col"]] = val
                return result

            name = form.name.data
            id = None
            if request.args.get('preview'):
                name += '(' + _('Preview') + ')'
                id = 0
            report_id = create_report(form.data_set, name=name, creator=form.creator.data,
                                      description=form.description.data, id=id, columns=form.columns.data,
                                      filters=parse_filters(json.loads(form.filters.data)))
            return jsonify({'id': report_id, 'name': form.name.data, 'url': url_for('.report', id_=report_id)})
        else:
            return jsonify({'errors': form.errors}), 403
コード例 #3
0
ファイル: scheduler.py プロジェクト: sarvex/CouchPotato
class Scheduler(Plugin):

    crons = {}
    intervals = {}
    started = False

    def __init__(self):

        add_event('schedule.cron', self.cron)
        add_event('schedule.interval', self.interval)
        add_event('schedule.remove', self.remove)
        add_event('schedule.queue', self.queue)

        self.sched = BackgroundScheduler(misfire_grace_time=60)
        self.sched.start()
        self.started = True

    def remove(self, identifier):
        for cron_type in ['intervals', 'crons']:
            try:
                self.sched.unschedule_job(
                    getattr(self, cron_type)[identifier]['job'])
                log.debug('%s unscheduled %s',
                          (cron_type.capitalize(), identifier))
            except:
                pass

    def do_shutdown(self, *args, **kwargs):
        self.stop()
        return super(Scheduler, self).do_shutdown(*args, **kwargs)

    def stop(self):
        if self.started:
            log.debug('Stopping scheduler')
            self.sched.shutdown(wait=False)
            log.debug('Scheduler stopped')
        self.started = False

    def cron(self, identifier='', handle=None, day='*', hour='*', minute='*'):
        log.info('Scheduling "%s", cron: day = %s, hour = %s, minute = %s',
                 (identifier, day, hour, minute))

        self.remove(identifier)
        self.crons[identifier] = {
            'handle':
            handle,
            'day':
            day,
            'hour':
            hour,
            'minute':
            minute,
            'job':
            self.sched.add_cron_job(handle, day=day, hour=hour, minute=minute)
        }

    def interval(self,
                 identifier='',
                 handle=None,
                 hours=0,
                 minutes=0,
                 seconds=0):
        log.info(
            'Scheduling %s, interval: hours = %s, minutes = %s, seconds = %s',
            (identifier, hours, minutes, seconds))

        self.remove(identifier)
        self.intervals[identifier] = {
            'handle':
            handle,
            'hours':
            hours,
            'minutes':
            minutes,
            'seconds':
            seconds,
            'job':
            self.sched.add_interval_job(handle,
                                        hours=hours,
                                        minutes=minutes,
                                        seconds=seconds)
        }

        return True

    def queue(self, handlers=None):
        if not handlers: handlers = []

        for h in handlers:
            h()

            if self.shuttingDown():
                break

        return True
コード例 #4
0
ファイル: run.py プロジェクト: hezhenke/quantdata
# -*- coding:utf-8 -*-
"""
Demonstrates how to use the background scheduler to schedule a job that executes on 3 second
intervals.
"""

from datetime import datetime
import time
import os

from apscheduler.schedulers.background import BackgroundScheduler

import pb,pe


if __name__ == '__main__':
    scheduler = BackgroundScheduler()
    scheduler.add_cron_job(pb.run, day_of_week="1-5", hour='16',minute=30)
    scheduler.add_cron_job(pe.run, day_of_week="1-5", hour='16',minute=40)
    scheduler.start()
    print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))

    try:
        # This is here to simulate application activity (which keeps the main thread alive).
        while True:
            time.sleep(2)
    except (KeyboardInterrupt, SystemExit):
        # Not strictly necessary if daemonic mode is enabled but should be done if possible
        scheduler.shutdown()
コード例 #5
0
ファイル: run.py プロジェクト: listonejava/quantdata
# -*- coding:utf-8 -*-
"""
Demonstrates how to use the background scheduler to schedule a job that executes on 3 second
intervals.
"""

from datetime import datetime
import time
import os

from apscheduler.schedulers.background import BackgroundScheduler

import pb, pe

if __name__ == '__main__':
    scheduler = BackgroundScheduler()
    scheduler.add_cron_job(pb.run, day_of_week="1-5", hour='16', minute=30)
    scheduler.add_cron_job(pe.run, day_of_week="1-5", hour='16', minute=40)
    scheduler.start()
    print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))

    try:
        # This is here to simulate application activity (which keeps the main thread alive).
        while True:
            time.sleep(2)
    except (KeyboardInterrupt, SystemExit):
        # Not strictly necessary if daemonic mode is enabled but should be done if possible
        scheduler.shutdown()