aboutsummaryrefslogtreecommitdiff
path: root/jobs/__init__.py
diff options
context:
space:
mode:
authorTom Ritter <tom@ritter.vg>2016-01-25 21:24:41 -0500
committerTom Ritter <tom@ritter.vg>2016-01-25 21:24:41 -0500
commit9b25f65ca655a567873c66c2b015884a3e013276 (patch)
tree242b994394ebbbcfdcc72eba6241f4ea03cf921c /jobs/__init__.py
Initial commit of checker
Diffstat (limited to 'jobs/__init__.py')
-rwxr-xr-xjobs/__init__.py86
1 files changed, 86 insertions, 0 deletions
diff --git a/jobs/__init__.py b/jobs/__init__.py
new file mode 100755
index 0000000..9955164
--- /dev/null
+++ b/jobs/__init__.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import inspect
+import logging
+from imp import load_module, find_module
+import importlib
+
+import jobs
+import jobs.JobBase
+import jobs.JobSpawner
+
+class JobFinder:
+ def __init__(self, config):
+ """
+ Opens the jobs folder and looks at every .py module in that directory.
+ Finds available jobs by looking at any class defined in those modules
+ that implements the JobBase abstract class.
+ Returns a list of job classes.
+ """
+ self._jobs = set([])
+ self.config = config
+
+ job_modules = self.get_job_modules_dynamic()
+
+ for module in job_modules:
+ # Check every declaration in that module
+ for name in dir(module):
+ obj = getattr(module, name)
+ if name not in module.__name__:
+ # Jobs have to have the same class name as their module name
+ # This prevents Job B from being detected twice when there is a Job A that imports Job B
+ continue
+
+ if inspect.isclass(obj):
+ # A class declaration was found in that module
+ # Checking if it's a subclass of JobBase
+ # Discarding JobBase as a subclass of JobBase
+ if obj != jobs.JobBase.JobBase and obj != jobs.JobSpawner.JobSpawner:
+ logging.info("Found " + str(obj))
+ for base in obj.__bases__:
+ # H4ck because issubclass() doesn't seem to work as expected on Linux
+ # It has to do with JobBase being imported multiple times (within jobs) or something
+ if base.__name__ == 'JobBase':
+ # A job was found, keep it
+ self._jobs.add(obj())
+ elif base.__name__ == 'JobSpawner':
+ spawner = obj()
+ for j in spawner.get_sub_jobs():
+ self._jobs.add(j)
+
+
+ def get_job_modules_dynamic(self):
+ job_modules = []
+
+ job_dir = jobs.__path__[0]
+ full_job_dir = os.path.join(sys.path[0], job_dir)
+ if os.path.exists(full_job_dir):
+ for (root, dirs, files) in os.walk(full_job_dir):
+ del dirs[:] # Do not walk into subfolders of the job directory
+ # Checking every .py module in the job directory
+ jobs_loaded = []
+ for source in (s for s in files if s.endswith((".py"))):
+ module_name = os.path.splitext(os.path.basename(source))[0]
+ if module_name in jobs_loaded:
+ continue
+ jobs_loaded.append(module_name)
+ full_name = os.path.splitext(source)[0].replace(os.path.sep,'.')
+
+ try: # Try to import the job package
+ # The job package HAS to be imported as a submodule
+ # of module 'jobs' or it will break windows compatibility
+ (file, pathname, description) = \
+ find_module(full_name, jobs.__path__)
+ module = load_module('jobs.' + full_name, file,
+ pathname, description)
+ except Exception as e:
+ logging.critical('Import Error on ' + module_name + ': ' + str(e))
+ jobs.JobBase.sendEmail(self.config, 'Import Error on ' + module_name, str(e))
+ continue
+ job_modules.append(module)
+ return job_modules
+
+ def get_jobs(self):
+ return self._jobs \ No newline at end of file