1import sys 2from argparse import ArgumentParser, ArgumentTypeError 3 4from sqlalchemy.orm.exc import NoResultFound 5 6from flexget import options 7from flexget.event import event 8from flexget.manager import Session 9from flexget.terminal import TerminalTable, colorize, console, disable_colors, table_parser 10 11from . import db 12 13 14def valid_entry(value): 15 try: 16 int(value) 17 except ValueError: 18 if value != 'all': 19 raise ArgumentTypeError('Must select \'all\' or valid entry ID') 20 return value 21 22 23def do_cli(manager, options): 24 if hasattr(options, 'table_type') and options.table_type == 'porcelain': 25 disable_all_colors() 26 27 if options.action == 'list': 28 list_entries(options) 29 elif options.action == 'approve': 30 manage_entries(options, options.selection, True) 31 elif options.action == 'reject': 32 manage_entries(options, options.selection, False) 33 elif options.action == 'clear': 34 clear_entries(options) 35 36 37def list_entries(options): 38 """List pending entries""" 39 approved = options.approved 40 task_name = options.task_name 41 42 with Session() as session: 43 entries = db.list_pending_entries(session=session, task_name=task_name, approved=approved) 44 header = ['#', 'Task Name', 'Title', 'URL', 'Approved', 'Added'] 45 table = TerminalTable(*header, table_type=options.table_type) 46 for entry in entries: 47 table.add_row( 48 str(entry.id), 49 entry.task_name, 50 entry.title, 51 entry.url, 52 colorize('green', 'Yes') if entry.approved else 'No', 53 entry.added.strftime("%c"), 54 ) 55 console(table) 56 57 58def manage_entries(options, selection, approved): 59 """Manage pending entries""" 60 approved_text = 'approved' if approved else 'pending' 61 with Session() as session: 62 if selection == 'all': 63 entries = db.list_pending_entries(session=session, approved=not approved) 64 else: 65 try: 66 entry = db.get_entry_by_id(session, selection) 67 if entry.approved is approved: 68 console( 69 colorize('red', 'ERROR: ') 70 + 'Entry with ID %s is already %s' % (entry.id, approved_text) 71 ) 72 sys.exit(1) 73 except NoResultFound: 74 console('Pending entry with ID %s does not exist' % selection) 75 sys.exit(1) 76 else: 77 entries = [entry] 78 if not entries: 79 console('All entries are already %s' % approved_text) 80 return 81 for entry in entries: 82 if entry.approved is not approved: 83 console( 84 'Setting pending entry with ID %s status to %s' % (entry.id, approved_text) 85 ) 86 entry.approved = approved 87 88 89def clear_entries(options): 90 """Clear pending entries""" 91 with Session() as session: 92 query = session.query(db.PendingEntry).filter(db.PendingEntry.approved == False) 93 if options.task_name: 94 query = query.filter(db.PendingEntry.task_name == options.task_name) 95 deleted = query.delete() 96 console('Successfully deleted %i pending entries' % deleted) 97 98 99@event('options.register') 100def register_parser_arguments(): 101 selection_parser = ArgumentParser(add_help=False) 102 selection_parser.add_argument( 103 'selection', type=valid_entry, help='Entity ID or \'all\' to approve all pending entries' 104 ) 105 106 filter_parser = ArgumentParser(add_help=False) 107 filter_parser.add_argument('--task-name', help='Filter by task name') 108 109 parser = options.register_command('pending', do_cli, help='View and manage pending entries') 110 subparsers = parser.add_subparsers(title='actions', metavar='<action>', dest='action') 111 112 list_parser = subparsers.add_parser( 113 'list', help='Shows all existing pending entries', parents=[table_parser, filter_parser] 114 ) 115 116 list_group = list_parser.add_mutually_exclusive_group() 117 list_group.add_argument( 118 '--pending', 119 action='store_false', 120 help='Show only pending entries', 121 dest='approved', 122 default=None, 123 ) 124 list_group.add_argument( 125 '--approved', 126 action='store_true', 127 help='Show only approved entries', 128 dest='approved', 129 default=None, 130 ) 131 132 subparsers.add_parser('approve', help='Approve pending entries', parents=[selection_parser]) 133 subparsers.add_parser('reject', help='Reject pending entries', parents=[selection_parser]) 134 subparsers.add_parser('clear', help='Clear all pending entries', parents=[filter_parser]) 135