| 
									
										
										
										
											2018-05-15 06:43:22 -04:00
										 |  |  | #!/usr/bin/env python3 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import argparse | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import pathlib | 
					
						
							|  |  |  | import subprocess | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import yaml | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | try: | 
					
						
							|  |  |  |     _data_home = os.environ['XDG_DATA_HOME'] | 
					
						
							|  |  |  | except KeyError: | 
					
						
							|  |  |  |     _data_home = pathlib.Path(os.path.expanduser('~'), '.local', 'share') | 
					
						
							|  |  |  | SHARE_DIR = pathlib.Path(_data_home, 'rt-auto-remind') | 
					
						
							|  |  |  | SHARE_DIR.mkdir(parents=True, exist_ok=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Reminder: | 
					
						
							| 
									
										
										
										
											2018-05-15 09:07:23 -04:00
										 |  |  |     def __init__(self, key, min_days, max_days, search, body_file, | 
					
						
							| 
									
										
										
										
											2018-05-16 15:59:09 -04:00
										 |  |  |                  date_field='Due', action='correspond', dry_run=False, rt_args=None): | 
					
						
							| 
									
										
										
										
											2018-05-15 06:43:22 -04:00
										 |  |  |         self.key = key | 
					
						
							|  |  |  |         self.min_days_diff = int(min_days) | 
					
						
							|  |  |  |         self.max_days_diff = int(max_days) | 
					
						
							|  |  |  |         self.search = search | 
					
						
							|  |  |  |         self.date_field = date_field | 
					
						
							|  |  |  |         self.body_file = body_file | 
					
						
							|  |  |  |         self.action = action | 
					
						
							| 
									
										
										
										
											2018-05-16 09:33:18 -04:00
										 |  |  |         self.dry_run = dry_run | 
					
						
							| 
									
										
										
										
											2018-05-16 15:59:09 -04:00
										 |  |  |         self.rt_args = [] if rt_args is None else rt_args.copy() | 
					
						
							| 
									
										
										
										
											2018-05-16 09:33:18 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _remind_cmd(self): | 
					
						
							|  |  |  |         yield 'rt-auto-remind' | 
					
						
							|  |  |  |         if self.dry_run: | 
					
						
							|  |  |  |             yield '--dry-run' | 
					
						
							|  |  |  |         yield '--{}'.format(self.action) | 
					
						
							|  |  |  |         yield '--key' | 
					
						
							|  |  |  |         yield self.key | 
					
						
							|  |  |  |         yield self.date_field | 
					
						
							|  |  |  |         yield str(self.min_days_diff) | 
					
						
							|  |  |  |         yield str(self.max_days_diff) | 
					
						
							|  |  |  |         yield self.search | 
					
						
							|  |  |  |         yield str(self.body_file) | 
					
						
							| 
									
										
										
										
											2018-05-16 15:59:09 -04:00
										 |  |  |         yield from self.rt_args | 
					
						
							| 
									
										
										
										
											2018-05-15 06:43:22 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def remind_cmd(self): | 
					
						
							| 
									
										
										
										
											2018-05-16 09:33:18 -04:00
										 |  |  |         return list(self._remind_cmd()) | 
					
						
							| 
									
										
										
										
											2018-05-15 06:43:22 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def parse_arguments(arglist): | 
					
						
							|  |  |  |     parser = argparse.ArgumentParser() | 
					
						
							| 
									
										
										
										
											2018-05-16 09:33:18 -04:00
										 |  |  |     parser.add_argument( | 
					
						
							|  |  |  |         '--dry-run', '-n', | 
					
						
							|  |  |  |         action='store_true', | 
					
						
							|  |  |  |         help="Pass --dry-run to rt-auto-remind", | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-05-15 09:07:23 -04:00
										 |  |  |     parser.add_argument( | 
					
						
							|  |  |  |         '--template-dir', | 
					
						
							|  |  |  |         type=pathlib.Path, | 
					
						
							|  |  |  |         default=SHARE_DIR / 'templates', | 
					
						
							|  |  |  |         help="Directory to search for templates that aren't specified in the" | 
					
						
							|  |  |  |         " YAML file (default `%(default)s`)", | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-05-15 06:43:22 -04:00
										 |  |  |     parser.add_argument( | 
					
						
							|  |  |  |         'yaml_files', metavar='PATH', | 
					
						
							|  |  |  |         type=pathlib.Path, | 
					
						
							|  |  |  |         nargs='+', | 
					
						
							|  |  |  |         help="YAML file(s) with configuration of reminders to send out", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     return parser.parse_args(arglist) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def main(arglist=None, stdout=sys.stdout, stderr=sys.stderr): | 
					
						
							|  |  |  |     args = parse_arguments(arglist) | 
					
						
							|  |  |  |     failures = 0 | 
					
						
							|  |  |  |     for yaml_path in args.yaml_files: | 
					
						
							|  |  |  |         with yaml_path.open() as yaml_file: | 
					
						
							|  |  |  |             yaml_data = yaml.safe_load(yaml_file) | 
					
						
							| 
									
										
										
										
											2018-05-15 09:07:23 -04:00
										 |  |  |         for key, reminder_kwargs in yaml_data.items(): | 
					
						
							|  |  |  |             if 'body_file' not in reminder_kwargs: | 
					
						
							|  |  |  |                 reminder_kwargs['body_file'] = args.template_dir / (key + '.txt') | 
					
						
							| 
									
										
										
										
											2018-05-16 09:33:18 -04:00
										 |  |  |             if args.dry_run: | 
					
						
							|  |  |  |                 reminder_kwargs['dry_run'] = True | 
					
						
							| 
									
										
										
										
											2018-05-15 09:07:23 -04:00
										 |  |  |             reminder = Reminder(key, **reminder_kwargs) | 
					
						
							| 
									
										
										
										
											2018-05-15 06:43:22 -04:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 subprocess.run(reminder.remind_cmd(), check=True) | 
					
						
							|  |  |  |             except subprocess.CalledProcessError as error: | 
					
						
							|  |  |  |                 print("warning: reminder {} exited {}".format(key, error.returncode)) | 
					
						
							|  |  |  |                 failures += 1 | 
					
						
							|  |  |  |     if failures == 0: | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         return min(10 + failures, 99) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     exit(main()) |