[Pkg-privacy-commits] [onionbalance] 103/117: Revert "Remove schedule dependency"
Donncha O'Cearbahill
donncha-guest at moszumanska.debian.org
Wed Dec 16 23:18:54 UTC 2015
This is an automated email from the git hooks/post-receive script.
donncha-guest pushed a commit to branch debian/sid
in repository onionbalance.
commit e44fcd8b0b0e56fd0580e73b3d371d8f1cc27306
Author: Donncha O'Cearbhaill <donncha at donncha.is>
Date: Sat Dec 12 14:06:35 2015 +0100
Revert "Remove schedule dependency"
I removed the dependency on the schedule package by including the single
file directly in the OnionBalance package. This was a mistake. This commit
removes schedule for the source tree. I will now instead package
python-schedule seperately in Debian.
This reverts commit 8936c55e2ff8485896f858a43363899418b7b4fd.
Conflicts:
onionbalance/schedule.py
---
onionbalance/manager.py | 2 +-
onionbalance/schedule.py | 416 -----------------------------------------------
requirements.txt | 1 +
setup.py | 1 +
4 files changed, 3 insertions(+), 417 deletions(-)
diff --git a/onionbalance/manager.py b/onionbalance/manager.py
index 7b7f66e..9588576 100644
--- a/onionbalance/manager.py
+++ b/onionbalance/manager.py
@@ -12,12 +12,12 @@ import logging
# import Crypto.PublicKey
import stem
from stem.control import Controller, EventType
+import schedule
from onionbalance import log
from onionbalance import settings
from onionbalance import config
from onionbalance import eventhandler
-from onionbalance import schedule
import onionbalance.service
import onionbalance.instance
diff --git a/onionbalance/schedule.py b/onionbalance/schedule.py
deleted file mode 100644
index 5b9e66d..0000000
--- a/onionbalance/schedule.py
+++ /dev/null
@@ -1,416 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-Python job scheduling for humans.
-
-An in-process scheduler for periodic jobs that uses the builder pattern
-for configuration. Schedule lets you run Python functions (or any other
-callable) periodically at pre-determined intervals using a simple,
-human-friendly syntax.
-
-Inspired by Addam Wiggins' article "Rethinking Cron" [1] and the
-"clockwork" Ruby module [2][3].
-
-Features:
- - A simple to use API for scheduling jobs.
- - Very lightweight and no external dependencies.
- - Excellent test coverage.
- - Works with Python 2.7 and 3.3
-
-Usage:
- >>> import schedule
- >>> import time
-
- >>> def job(message='stuff'):
- >>> print("I'm working on:", message)
-
- >>> schedule.every(10).minutes.do(job)
- >>> schedule.every().hour.do(job, message='things')
- >>> schedule.every().day.at("10:30").do(job)
-
- >>> while True:
- >>> schedule.run_pending()
- >>> time.sleep(1)
-
-Copyright (c) 2013 Daniel Bader (http://dbader.org)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-[1] http://adam.heroku.com/past/2010/4/13/rethinking_cron/
-[2] https://github.com/tomykaira/clockwork
-[3] http://adam.heroku.com/past/2010/6/30/replace_cron_with_clockwork/
-"""
-import datetime
-import functools
-import logging
-import time
-
-logger = logging.getLogger('schedule')
-
-
-class CancelJob(object):
- pass
-
-
-class Scheduler(object):
- def __init__(self):
- self.jobs = []
-
- def run_pending(self):
- """Run all jobs that are scheduled to run.
-
- Please note that it is *intended behavior that tick() does not
- run missed jobs*. For example, if you've registered a job that
- should run every minute and you only call tick() in one hour
- increments then your job won't be run 60 times in between but
- only once.
- """
- runnable_jobs = (job for job in self.jobs if job.should_run)
- for job in sorted(runnable_jobs):
- self._run_job(job)
-
- def run_all(self, delay_seconds=0):
- """Run all jobs regardless if they are scheduled to run or not.
-
- A delay of `delay` seconds is added between each job. This helps
- distribute system load generated by the jobs more evenly
- over time."""
- logger.info('Running *all* %i jobs with %is delay inbetween',
- len(self.jobs), delay_seconds)
- for job in self.jobs:
- self._run_job(job)
- time.sleep(delay_seconds)
-
- def clear(self):
- """Deletes all scheduled jobs."""
- del self.jobs[:]
-
- def cancel_job(self, job):
- """Delete a scheduled job."""
- try:
- self.jobs.remove(job)
- except ValueError:
- pass
-
- def every(self, interval=1):
- """Schedule a new periodic job."""
- job = Job(interval)
- self.jobs.append(job)
- return job
-
- def _run_job(self, job):
- ret = job.run()
- if isinstance(ret, CancelJob) or ret is CancelJob:
- self.cancel_job(job)
-
- @property
- def next_run(self):
- """Datetime when the next job should run."""
- if not self.jobs:
- return None
- return min(self.jobs).next_run
-
- @property
- def idle_seconds(self):
- """Number of seconds until `next_run`."""
- return (self.next_run - datetime.datetime.now()).total_seconds()
-
-
-class Job(object):
- """A periodic job as used by `Scheduler`."""
- def __init__(self, interval):
- self.interval = interval # pause interval * unit between runs
- self.job_func = None # the job job_func to run
- self.unit = None # time units, e.g. 'minutes', 'hours', ...
- self.at_time = None # optional time at which this job runs
- self.last_run = None # datetime of the last run
- self.next_run = None # datetime of the next run
- self.period = None # timedelta between runs, only valid for
- self.start_day = None # Specific day of the week to start on
-
- def __lt__(self, other):
- """PeriodicJobs are sortable based on the scheduled time
- they run next."""
- return self.next_run < other.next_run
-
- def __repr__(self):
- def format_time(t):
- return t.strftime('%Y-%m-%d %H:%M:%S') if t else '[never]'
-
- timestats = '(last run: %s, next run: %s)' % (
- format_time(self.last_run), format_time(self.next_run))
-
- if hasattr(self.job_func, '__name__'):
- job_func_name = self.job_func.__name__
- else:
- job_func_name = repr(self.job_func)
- args = [repr(x) for x in self.job_func.args]
- kwargs = ['%s=%s' % (k, repr(v))
- for k, v in self.job_func.keywords.items()]
- call_repr = job_func_name + '(' + ', '.join(args + kwargs) + ')'
-
- if self.at_time is not None:
- return 'Every %s %s at %s do %s %s' % (
- self.interval,
- self.unit[:-1] if self.interval == 1 else self.unit,
- self.at_time, call_repr, timestats)
- else:
- return 'Every %s %s do %s %s' % (
- self.interval,
- self.unit[:-1] if self.interval == 1 else self.unit,
- call_repr, timestats)
-
- @property
- def second(self):
- assert self.interval == 1
- return self.seconds
-
- @property
- def seconds(self):
- self.unit = 'seconds'
- return self
-
- @property
- def minute(self):
- assert self.interval == 1
- return self.minutes
-
- @property
- def minutes(self):
- self.unit = 'minutes'
- return self
-
- @property
- def hour(self):
- assert self.interval == 1
- return self.hours
-
- @property
- def hours(self):
- self.unit = 'hours'
- return self
-
- @property
- def day(self):
- assert self.interval == 1
- return self.days
-
- @property
- def days(self):
- self.unit = 'days'
- return self
-
- @property
- def week(self):
- assert self.interval == 1
- return self.weeks
-
- @property
- def monday(self):
- assert self.interval == 1
- self.start_day = 'monday'
- return self.weeks
-
- @property
- def tuesday(self):
- assert self.interval == 1
- self.start_day = 'tuesday'
- return self.weeks
-
- @property
- def wednesday(self):
- assert self.interval == 1
- self.start_day = 'wednesday'
- return self.weeks
-
- @property
- def thursday(self):
- assert self.interval == 1
- self.start_day = 'thursday'
- return self.weeks
-
- @property
- def friday(self):
- assert self.interval == 1
- self.start_day = 'friday'
- return self.weeks
-
- @property
- def saturday(self):
- assert self.interval == 1
- self.start_day = 'saturday'
- return self.weeks
-
- @property
- def sunday(self):
- assert self.interval == 1
- self.start_day = 'sunday'
- return self.weeks
-
- @property
- def weeks(self):
- self.unit = 'weeks'
- return self
-
- def at(self, time_str):
- """Schedule the job every day at a specific time.
-
- Calling this is only valid for jobs scheduled to run every
- N day(s).
- """
- assert self.unit in ('days', 'hours') or self.start_day
- hour, minute = [t for t in time_str.split(':')]
- minute = int(minute)
- if self.unit == 'days' or self.start_day:
- hour = int(hour)
- assert 0 <= hour <= 23
- elif self.unit == 'hours':
- hour = 0
- assert 0 <= minute <= 59
- self.at_time = datetime.time(hour, minute)
- return self
-
- def do(self, job_func, *args, **kwargs):
- """Specifies the job_func that should be called every time the
- job runs.
-
- Any additional arguments are passed on to job_func when
- the job runs.
- """
- self.job_func = functools.partial(job_func, *args, **kwargs)
- try:
- functools.update_wrapper(self.job_func, job_func)
- except AttributeError:
- # job_funcs already wrapped by functools.partial won't have
- # __name__, __module__ or __doc__ and the update_wrapper()
- # call will fail.
- pass
- self._schedule_next_run()
- return self
-
- @property
- def should_run(self):
- """True if the job should be run now."""
- return datetime.datetime.now() >= self.next_run
-
- def run(self):
- """Run the job and immediately reschedule it."""
- logger.info('Running job %s', self)
- ret = self.job_func()
- self.last_run = datetime.datetime.now()
- self._schedule_next_run()
- return ret
-
- def _schedule_next_run(self):
- """Compute the instant when this job should run next."""
- # Allow *, ** magic temporarily:
- assert self.unit in ('seconds', 'minutes', 'hours', 'days', 'weeks')
- self.period = datetime.timedelta(**{self.unit: self.interval})
- self.next_run = datetime.datetime.now() + self.period
- if self.start_day is not None:
- assert self.unit == 'weeks'
- weekdays = (
- 'monday',
- 'tuesday',
- 'wednesday',
- 'thursday',
- 'friday',
- 'saturday',
- 'sunday'
- )
- assert self.start_day in weekdays
- weekday = weekdays.index(self.start_day)
- days_ahead = weekday - self.next_run.weekday()
- if days_ahead <= 0: # Target day already happened this week
- days_ahead += 7
- self.next_run += datetime.timedelta(days_ahead) - self.period
- if self.at_time is not None:
- assert self.unit in ('days', 'hours') or self.start_day is not None
- kwargs = {
- 'minute': self.at_time.minute,
- 'second': self.at_time.second,
- 'microsecond': 0
- }
- if self.unit == 'days' or self.start_day is not None:
- kwargs['hour'] = self.at_time.hour
- self.next_run = self.next_run.replace(**kwargs)
- # If we are running for the first time, make sure we run
- # at the specified time *today* (or *this hour*) as well
- if not self.last_run:
- now = datetime.datetime.now()
- if (self.unit == 'days' and self.at_time > now.time() and
- self.interval == 1):
- self.next_run = self.next_run - datetime.timedelta(days=1)
- elif self.unit == 'hours' and self.at_time.minute > now.minute:
- self.next_run = self.next_run - datetime.timedelta(hours=1)
- if self.start_day is not None and self.at_time is not None:
- # Let's see if we will still make that time we specified today
- if (self.next_run - datetime.datetime.now()).days >= 7:
- self.next_run -= self.period
-
-# The following methods are shortcuts for not having to
-# create a Scheduler instance:
-
-default_scheduler = Scheduler()
-jobs = default_scheduler.jobs # todo: should this be a copy, e.g. jobs()?
-
-
-def every(interval=1):
- """Schedule a new periodic job."""
- return default_scheduler.every(interval)
-
-
-def run_pending():
- """Run all jobs that are scheduled to run.
-
- Please note that it is *intended behavior that run_pending()
- does not run missed jobs*. For example, if you've registered a job
- that should run every minute and you only call run_pending()
- in one hour increments then your job won't be run 60 times in
- between but only once.
- """
- default_scheduler.run_pending()
-
-
-def run_all(delay_seconds=0):
- """Run all jobs regardless if they are scheduled to run or not.
-
- A delay of `delay` seconds is added between each job. This can help
- to distribute the system load generated by the jobs more evenly over
- time."""
- default_scheduler.run_all(delay_seconds=delay_seconds)
-
-
-def clear():
- """Deletes all scheduled jobs."""
- default_scheduler.clear()
-
-
-def cancel_job(job):
- """Delete a scheduled job."""
- default_scheduler.cancel_job(job)
-
-
-def next_run():
- """Datetime when the next job should run."""
- return default_scheduler.next_run
-
-
-def idle_seconds():
- """Number of seconds until `next_run`."""
- return default_scheduler.idle_seconds
diff --git a/requirements.txt b/requirements.txt
index 5313a02..1394418 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,5 @@
stem==1.4.1b
PyYAML==3.11
pycrypto==2.6.1
+schedule==0.3.1
future==0.14.3
diff --git a/setup.py b/setup.py
index bc254fe..897ec20 100644
--- a/setup.py
+++ b/setup.py
@@ -44,6 +44,7 @@ setup(
'stem>=1.4.0-dev',
'PyYAML>=3.11',
'pycrypto>=2.6.1',
+ 'schedule>=0.3.1',
'future>=0.14.0',
],
tests_require=['tox', 'pytest-mock', 'pytest', 'mock', 'pexpect'],
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/onionbalance.git
More information about the Pkg-privacy-commits
mailing list