Example #1
0
class TestConfigHandler(unittest.TestCase):
    MOCK_FILE = get_dir_path()
    VALID_OPTIONS = get_valid_options()

    def setUp(self):
        self.cfg = ConfigHandler()
        logging.disable(logging.CRITICAL)

    def tearDown(self):
        logging.disable(logging.NOTSET)

    def test_available_reddit_clients(self):
        sections = ['DEFAULTS', 'USERS', 'EMPTY_CLIENT', 'FIRST', 'SECOND']
        with patch.object(ConfigHandler,
                          'get_config_sections',
                          return_value=sections):
            self.assertEqual(self.cfg.get_available_reddit_clients(),
                             ['FIRST', 'SECOND'])

    @mock.patch('builtins.open', new_callable=mock_open())
    @mock.patch('myredditdl.config_handler.ConfigHandler.get_config_path')
    @mock.patch(
        'myredditdl.config_handler.ConfigHandler.get_client_active_section')
    def test_add_client(self, client, cfg_path, mock_open):
        client.return_value = 'EMPTY_CLIENT'
        cfg_path.return_value = self.MOCK_FILE
        self.assertFalse(self.cfg.add_client(get_new_client('EMPTY_CLIENT')))
        self.assertTrue(self.cfg.add_client(get_new_client('NEW_USER')))

    @mock.patch('builtins.open', new_callable=mock_open())
    @mock.patch('myredditdl.config_handler.ConfigHandler.get_config_path')
    @mock.patch(
        'myredditdl.config_handler.ConfigHandler.get_client_active_section')
    def test_set_new_current_user(self, client, cfg_path, mock_open):
        client.return_value = 'EMPTY_CLIENT'
        cfg_path.return_value = self.MOCK_FILE
        self.assertFalse(self.cfg.set_new_current_user('EMPTY_CLIENT'))
        self.assertFalse(self.cfg.set_new_current_user('EMPTY_CLIENT'))
        self.assertTrue(self.cfg.set_new_current_user('new_user'))

    @mock.patch(
        'myredditdl.config_handler.ConfigHandler.get_valid_prefix_options')
    @mock.patch('myredditdl.config_handler.ConfigHandler.get_prefix')
    def test_set_prefix_option(self, mock_prefix, mock_options):
        mock_prefix.return_value = 'subreddit_name'
        mock_options.return_value = self.VALID_OPTIONS
        self.assertFalse(self.cfg.set_prefix_option('subreddit_name'))
        self.assertTrue(self.cfg.set_prefix_option('username'))
        self.assertTrue(self.cfg.set_prefix_option('username_subreddit'))
        self.assertFalse(self.cfg.set_prefix_option('sub_name'))

    def test_default_media_path(self):
        home = os.path.expanduser('~/Pictures/')
        with patch.object(ConfigHandler,
                          'get_client_active_section',
                          return_value='SATORU'):
            self.assertEqual(self.cfg.get_default_media_path(),
                             home + 'SATORU_reddit' + os.sep)
Example #2
0
def __mapped_config_requests():
    terminal = Terminal()
    return {
        'add_client': terminal.client_setup,
        'change_client': terminal.change_client,
        'show_config': ConfigHandler().__print__,
        'path': terminal.change_path,
        'prefix': terminal.change_prefix
    }
Example #3
0
class Defaults:
    def __init__(self, debug=False) -> None:
        self.log = utils.setup_logger(__name__)
        self.config_handler = ConfigHandler()

    @property
    def home_dir(self) -> str:
        return os.path.expanduser('~')

    @property
    def project_parent_dir(self) -> str:
        return str(pathlib.Path(__file__).parent.parent) + os.sep

    @property
    def src_dir(self) -> str:
        ''' Source files folder'''
        return str(pathlib.Path(__file__).parent) + os.sep

    @property
    def media_folder(self) -> str:
        return self.src_dir + 'media' + os.sep

    @property
    def debug_log_file(self) -> str:
        return self.src_dir + os.sep + 'debug.log'

    @property
    def debug_path(self) -> str:
        return str(self.project_parent_dir + 'debug_media' + os.sep)

    @property
    def metadata_file(self) -> str:
        ''' Returns the full path of the metadata file'''
        return self.media_folder + self.client_username + '_metadata.json'

    @property
    def media_path(self):
        return self.config_handler.get_media_path()

    @property
    def current_prefix(self):
        return self.config_handler.get_prefix()
Example #4
0
 def __init__(self) -> None:
     self.client_time = time.time()
     self.arg_dict = console_args.get_console_args()
     self.logger = utils.setup_logger(__name__, self.arg_dict['debug'])
     self.conf = ConfigHandler()
     self.user_instance = None
Example #5
0
class RedditClient:
    def __init__(self) -> None:
        self.client_time = time.time()
        self.arg_dict = console_args.get_console_args()
        self.logger = utils.setup_logger(__name__, self.arg_dict['debug'])
        self.conf = ConfigHandler()
        self.user_instance = None

    @property
    def section_name(self):
        return self.conf.get_client_active_section()

    @property
    def config(self):
        return self.conf.get_config()

    @property
    def max_depth(self):
        return self.arg_dict['max_depth']

    @property
    def client_upvotes(self) -> 'User upvoted posts':
        ''' Yields a ListingGenerator of the user upvoted posts if the
            user asked for the saved files with the (-U --upvote) flag.
            Otherwise, return None
        '''
        return self.user_instance.upvoted(
            limit=self.arg_dict['max_depth']
        ) if self.arg_dict['upvote'] else None

    @property
    def client_saves(self) -> 'User saved posts':
        ''' Yields a ListingGenerator of the user saved posts if the
            user asked for the saved files with the (-S --saved) flag.
            Otherwise, return None
        '''
        return self.user_instance.saved(limit=self.arg_dict['max_depth']
                                        ) if self.arg_dict['saved'] else None

    def build_reddit_instance(self) -> bool:
        self.logger.info('Building reddit instance...')

        if len(self.section_name) == 0:
            self.logger.warning(
                'No valid clients were found.'
                'Add new reddit clients with the --add-client flag')
            return False

        try:
            self.user_instance = praw.Reddit(
                user_agent='myredditdl',
                client_id=self.config[self.section_name]['client_id'],
                client_secret=self.config[self.section_name]['client_secret'],
                username=self.config[self.section_name]['username'],
                password=self.config[self.section_name]['password']).user.me()

        except Exception:
            self.logger.error('Reddit instance build: Failed!')
            return False

        self.logger.debug("Client: %s seconds" %
                          (time.time() - self.client_time))
        return True

    @classmethod
    def validate_instance(cls, instance: dict) -> bool:
        try:
            instance = praw.Reddit(
                user_agent='myredditdl',
                client_id=instance.get('client_id'),
                client_secret=instance.get('client_secret'),
                username=instance.get('username'),
                password=instance.get('password')).user.me()
            return True

        except Exception:
            print('INFO: instance validator: Failed!')

        return False
Example #6
0
 def __init__(self, debug=False) -> None:
     self.log = utils.setup_logger(__name__)
     self.config_handler = ConfigHandler()
Example #7
0
 def setUp(self):
     self.cfg = ConfigHandler()
     logging.disable(logging.CRITICAL)
Example #8
0
 def __init__(self):
     self.log = utils.setup_logger(__name__)
     self.config = ConfigHandler()
Example #9
0
class Terminal:
    def __init__(self):
        self.log = utils.setup_logger(__name__)
        self.config = ConfigHandler()

    def display_setup_header(self) -> None:
        instructions = utils.DEVELOPER_APP_INSTRUCTIONS
        header = '-' * 20 + ' SETUP CONFIGURATOR ' + '-' * 20
        print('\n' + header)
        print(
            'For information'
            ' on how to setup your own developer credentials to use myredditdl,\n'
            'Please refer to',
            instructions)

        print(
            '\nInput your reddit developer credentials below. Make sure they are correct.')
        print('-' * len(header))

    def new_client_prompt(self) -> dict:
        ''' Prompts the user for new client information and returns the
            information as a dictionary.
        '''
        client_id = input('1. Client Id: ').strip(' ')
        client_secret = input('2. Client secret: ').strip(' ')
        username = input('3. Username: '******' ')
        password = input('4. Password: '******' ')
        print('\n')

        return {'section': username.upper(),
                'client_id': client_id,
                'client_secret': client_secret,
                'username': username,
                'password': password}

    def client_setup(self, request=None) -> None:
        ''' Sets up new Reddit client if the given credentials are valid
            Reddit instances. If valid, then go ahead an add the client.
            If invalid; exit the program.
        '''
        self.display_setup_header()
        new_client_instance = self.new_client_prompt()

        if RedditClient.validate_instance(new_client_instance):
            self.config.add_client(new_client_instance)
        else:
            self.log.warning('Invalid reddit instance provided')
            exit(0)

    def change_client_prompt(self, options: dict) -> None:
        print('\n Valid Reddit Clients:\n')
        for k, v in options.items():
            print(f'{k}. {v}')

        res = ''
        while res not in options.keys():
            res = input('\nPlease, chose a client to change to: ')

        if res == str(len(options)):
            self.log.info('Thank you for using myredditdl')
            exit(0)
        self.config.set_new_current_user(options.get(res))

    def get_clients_options(self) -> dict:
        clients = self.config.get_available_reddit_clients()
        clients.append('Exit program')
        return {str(index): client for index, client in enumerate(clients, 1)}

    def change_client(self, request=None):
        options = self.get_clients_options()
        self.change_client_prompt(options)

    def change_path(self, request: str):
        self.config.set_media_path(request)

    def change_prefix(self, request: list):
        self.config.set_prefix_option('_'.join(request))