From f4d3c5a40f84d4f5959c81f79f1e5da695958acc Mon Sep 17 00:00:00 2001 From: Skenvy <17214791+Skenvy@users.noreply.github.com> Date: Fri, 22 Jan 2021 00:43:40 +1100 Subject: [PATCH 1/3] Added way to retrieve existing jobs per tags. --- docs/examples.rst | 39 +++++++++++++++++++++++++++++++++++++++ docs/reference.rst | 1 + schedule/__init__.py | 20 ++++++++++++++++++++ test_schedule.py | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+) diff --git a/docs/examples.rst b/docs/examples.rst index 072693d6..a616b8b9 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -99,6 +99,44 @@ Return ``schedule.CancelJob`` from a job to remove it from the scheduler. time.sleep(1) +Get all jobs +~~~~~~~~~~~~ +To retrieve all jobs from the scheduler, use ``schedule.get_jobs()`` + +.. code-block:: python + + import schedule + + def hello(): + print('Hello world') + + schedule.every().second.do(hello) + + all_jobs = schedule.get_jobs() + + +Get several jobs, filtered by tags +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can retrieve a group of jobs from the scheduler, selecting them by a unique identifier. + +.. code-block:: python + + import schedule + + def greet(name): + print('Hello {}'.format(name)) + + schedule.every().day.do(greet, 'Andrea').tag('daily-tasks', 'friend') + schedule.every().hour.do(greet, 'John').tag('hourly-tasks', 'friend') + schedule.every().hour.do(greet, 'Monica').tag('hourly-tasks', 'customer') + schedule.every().day.do(greet, 'Derek').tag('daily-tasks', 'guest') + + friends = schedule.get_jobs('friend') + +Will return a list of every job tagged as ``friend``. + + Cancel all jobs ~~~~~~~~~~~~~~~ To remove all jobs from the scheduler, use ``schedule.clear()`` @@ -136,6 +174,7 @@ You can cancel the scheduling of a group of jobs selecting them by a unique iden Will prevent every job tagged as ``daily-tasks`` from running again. + Run a job at random intervals ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/reference.rst b/docs/reference.rst index 6947af41..9faff677 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -14,6 +14,7 @@ Main Interface .. autofunction:: every .. autofunction:: run_pending .. autofunction:: run_all +.. autofunction:: get_jobs .. autofunction:: clear .. autofunction:: cancel_job .. autofunction:: next_run diff --git a/schedule/__init__.py b/schedule/__init__.py index dae14465..adbc5650 100644 --- a/schedule/__init__.py +++ b/schedule/__init__.py @@ -109,6 +109,19 @@ def run_all(self, delay_seconds=0): self._run_job(job) time.sleep(delay_seconds) + def get_jobs(self, tag=None): + """ + Gets scheduled jobs marked with the given tag, or all jobs + if tag is omitted. + + :param tag: An identifier used to identify a subset of + jobs to retrieve + """ + if tag is None: + return self.jobs[:] + else: + return [job for job in self.jobs if tag in job.tags] + def clear(self, tag=None): """ Deletes scheduled jobs marked with the given tag, or all jobs @@ -599,6 +612,13 @@ def run_all(delay_seconds=0): default_scheduler.run_all(delay_seconds=delay_seconds) +def get_jobs(tag=None): + """Calls :meth:`get_jobs ` on the + :data:`default scheduler instance `. + """ + return default_scheduler.get_jobs(tag) + + def clear(tag=None): """Calls :meth:`clear ` on the :data:`default scheduler instance `. diff --git a/test_schedule.py b/test_schedule.py index 716a396b..6dd570eb 100644 --- a/test_schedule.py +++ b/test_schedule.py @@ -557,6 +557,40 @@ def test_tag_type_enforcement(self): job1.tag(0, 'a', True) assert len(job1.tags) == 3 + def test_get_by_tag(self): + every().second.do(make_mock_job()).tag('job1', 'tag1') + every().second.do(make_mock_job()).tag('job2', 'tag2', 'tag4') + every().second.do(make_mock_job()).tag('job3', 'tag3', 'tag4') + # Test None input yields all 3 + jobs = schedule.get_jobs() + assert len(jobs) == 3 + all_tags = jobs[0].tags.copy() + all_tags.update(jobs[1].tags, jobs[2].tags) + jobs_names = [name for name in all_tags if 'job' in name] + assert set(jobs_names) == set(['job1', 'job2', 'job3']) + # Test each 1:1 tag:job + jobs = schedule.get_jobs('tag1') + assert len(jobs) == 1 + assert 'job1' in jobs[0].tags + jobs = schedule.get_jobs('tag2') + assert len(jobs) == 1 + assert 'job2' in jobs[0].tags + jobs = schedule.get_jobs('tag3') + assert len(jobs) == 1 + assert 'job3' in jobs[0].tags + # Test multiple jobs found. + jobs = schedule.get_jobs('tag4') + assert len(jobs) == 2 + all_tags = jobs[0].tags.copy() + all_tags.update(jobs[1].tags) + jobs_names = [name for name in all_tags if 'job' in name] + assert set(jobs_names) == set(['job2', 'job3']) + # Test no tag. + jobs = schedule.get_jobs('tag5') + assert len(jobs) == 0 + schedule.clear() + assert len(schedule.jobs) == 0 + def test_clear_by_tag(self): every().second.do(make_mock_job(name='job1')).tag('tag1') every().second.do(make_mock_job(name='job2')).tag('tag1', 'tag2') From 210f17dba46b6f40b9656dc4dd23e28ced665f7f Mon Sep 17 00:00:00 2001 From: sijmenhuizenga Date: Sun, 31 Jan 2021 23:27:31 +0100 Subject: [PATCH 2/3] Minor changes tag-based job retrieval --- AUTHORS.rst | 1 + docs/examples.rst | 34 +++++++++++++++++----------------- test_schedule.py | 20 ++++++-------------- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index 2734387e..7e394a1c 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -21,3 +21,4 @@ Thanks to all the wonderful folks who have contributed to schedule over the year - aisk - MichaelCorleoneLi - SijmenHuizenga +- Skenvy \ No newline at end of file diff --git a/docs/examples.rst b/docs/examples.rst index a616b8b9..09a23fe0 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -115,10 +115,9 @@ To retrieve all jobs from the scheduler, use ``schedule.get_jobs()`` all_jobs = schedule.get_jobs() -Get several jobs, filtered by tags -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can retrieve a group of jobs from the scheduler, selecting them by a unique identifier. +Cancel all jobs +~~~~~~~~~~~~~~~ +To remove all jobs from the scheduler, use ``schedule.clear()`` .. code-block:: python @@ -127,19 +126,15 @@ You can retrieve a group of jobs from the scheduler, selecting them by a unique def greet(name): print('Hello {}'.format(name)) - schedule.every().day.do(greet, 'Andrea').tag('daily-tasks', 'friend') - schedule.every().hour.do(greet, 'John').tag('hourly-tasks', 'friend') - schedule.every().hour.do(greet, 'Monica').tag('hourly-tasks', 'customer') - schedule.every().day.do(greet, 'Derek').tag('daily-tasks', 'guest') + schedule.every().second.do(greet) - friends = schedule.get_jobs('friend') + schedule.clear() -Will return a list of every job tagged as ``friend``. +Get several jobs, filtered by tags +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Cancel all jobs -~~~~~~~~~~~~~~~ -To remove all jobs from the scheduler, use ``schedule.clear()`` +You can retrieve a group of jobs from the scheduler, selecting them by a unique identifier. .. code-block:: python @@ -148,13 +143,18 @@ To remove all jobs from the scheduler, use ``schedule.clear()`` def greet(name): print('Hello {}'.format(name)) - schedule.every().second.do(greet) + schedule.every().day.do(greet, 'Andrea').tag('daily-tasks', 'friend') + schedule.every().hour.do(greet, 'John').tag('hourly-tasks', 'friend') + schedule.every().hour.do(greet, 'Monica').tag('hourly-tasks', 'customer') + schedule.every().day.do(greet, 'Derek').tag('daily-tasks', 'guest') - schedule.clear() + friends = schedule.get_jobs('friend') + +Will return a list of every job tagged as ``friend``. -Cancel several jobs at once -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Cancel several jobs, filtered by tags +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can cancel the scheduling of a group of jobs selecting them by a unique identifier. diff --git a/test_schedule.py b/test_schedule.py index 6dd570eb..2701eda0 100644 --- a/test_schedule.py +++ b/test_schedule.py @@ -561,30 +561,22 @@ def test_get_by_tag(self): every().second.do(make_mock_job()).tag('job1', 'tag1') every().second.do(make_mock_job()).tag('job2', 'tag2', 'tag4') every().second.do(make_mock_job()).tag('job3', 'tag3', 'tag4') + # Test None input yields all 3 jobs = schedule.get_jobs() assert len(jobs) == 3 - all_tags = jobs[0].tags.copy() - all_tags.update(jobs[1].tags, jobs[2].tags) - jobs_names = [name for name in all_tags if 'job' in name] - assert set(jobs_names) == set(['job1', 'job2', 'job3']) + assert {'job1', 'job2', 'job3'}.issubset({*jobs[0].tags, *jobs[1].tags, *jobs[2].tags}) + # Test each 1:1 tag:job jobs = schedule.get_jobs('tag1') assert len(jobs) == 1 assert 'job1' in jobs[0].tags - jobs = schedule.get_jobs('tag2') - assert len(jobs) == 1 - assert 'job2' in jobs[0].tags - jobs = schedule.get_jobs('tag3') - assert len(jobs) == 1 - assert 'job3' in jobs[0].tags + # Test multiple jobs found. jobs = schedule.get_jobs('tag4') assert len(jobs) == 2 - all_tags = jobs[0].tags.copy() - all_tags.update(jobs[1].tags) - jobs_names = [name for name in all_tags if 'job' in name] - assert set(jobs_names) == set(['job2', 'job3']) + assert 'job1' not in {*jobs[0].tags, *jobs[1].tags} + # Test no tag. jobs = schedule.get_jobs('tag5') assert len(jobs) == 0 From 4e42fe3163ffc6dbba7a08287bc5fe323a885e7c Mon Sep 17 00:00:00 2001 From: sijmenhuizenga Date: Sun, 31 Jan 2021 23:31:48 +0100 Subject: [PATCH 3/3] Fix flake8 --- test_schedule.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test_schedule.py b/test_schedule.py index 2701eda0..099336a3 100644 --- a/test_schedule.py +++ b/test_schedule.py @@ -565,7 +565,8 @@ def test_get_by_tag(self): # Test None input yields all 3 jobs = schedule.get_jobs() assert len(jobs) == 3 - assert {'job1', 'job2', 'job3'}.issubset({*jobs[0].tags, *jobs[1].tags, *jobs[2].tags}) + assert {'job1', 'job2', 'job3'}\ + .issubset({*jobs[0].tags, *jobs[1].tags, *jobs[2].tags}) # Test each 1:1 tag:job jobs = schedule.get_jobs('tag1')