Example #1
0
def test_override(monkeypatch, short, equals):
    """Test overriding env variables with command line.

    :param monkeypatch: pytest fixture.
    :param bool short: Use short arg names.
    :param bool equals: Use ['--key=val'] or ['-kval'] instead of ['--key', 'val'].
    """
    monkeypatch.setenv("FAM_FFMPEG_BIN", "/tmp/ffmpeg")
    monkeypatch.setenv("FAM_VERBOSE", "False")

    if equals and short:
        argv = ["run", "-f/tmp/arg/ffmpeg", "-v"]
    elif equals:
        argv = ["run", "--ffmpeg-bin=/tmp/arg/ffmpeg", "--verbose"]
    else:
        argv = ["run", "--ffmpeg-bin", "/tmp/arg/ffmpeg", "--verbose"]

    actual = docoptcfg(DOCSTRING_FAM, argv, env_prefix="FAM_")
    expected = EXPECTED_FAM.copy()
    expected["--ffmpeg-bin"] = "/tmp/arg/ffmpeg"
    expected["--verbose"] = True
    assert actual == expected

    actual = docoptcfg(DOCSTRING_FAM, ["run"], env_prefix="FAM_")
    expected = EXPECTED_FAM.copy()
    expected["--ffmpeg-bin"] = "/tmp/ffmpeg"
    expected["--verbose"] = False
    assert actual == expected
Example #2
0
def test_multi(monkeypatch, multi, set_key, set_key0, set_key1):
    """Test with repeatable non-boolean options.

    :param monkeypatch: pytest fixture.
    :param bool multi: Test with ... and without ... in docstring.
    :param str set_key: Set MULTI_KEY to this value if not None.
    :param str set_key0: Set MULTI_KEY0 to this value if not None.
    :param str set_key1: Set MULTI_KEY1 to this value if not None.
    """
    monkeypatch.setattr("sys.argv", ["pytest", "1", "--flag"])
    docstring = DOCSTRING_MULTI if multi else DOCSTRING_NOT_MULTI
    expected = EXPECTED_MULTI.copy() if multi else EXPECTED_NOT_MULTI.copy()
    expected["--flag"] = 1 if multi else True

    # Set variables.
    if set_key is not None:
        monkeypatch.setenv("MULTI_KEY", set_key)
    if set_key0 is not None:
        monkeypatch.setenv("MULTI_KEY0", set_key0)
    if set_key1 is not None:
        monkeypatch.setenv("MULTI_KEY1", set_key1)

    # Test not multi.
    if not multi:
        if set_key is not None:
            expected["--key"] = str(set_key)  # Others are ignored.
        actual = docoptcfg(docstring, env_prefix="MULTI_")
        assert actual == expected
        return

    set_keys = (set_key is not None, set_key0 is not None, set_key1 is not None)
    if set_keys == (True, True, True):
        expected["--key"] = [set_key, set_key0, set_key1]
    elif set_keys == (True, True, False):
        expected["--key"] = [set_key, set_key0]
    elif set_keys == (True, False, False):
        expected["--key"] = [set_key]

    elif set_keys == (False, False, False):
        expected["--key"] = []
    elif set_keys == (False, False, True):
        expected["--key"] = []
    elif set_keys == (False, True, True):
        expected["--key"] = [set_key0, set_key1]

    elif set_keys == (False, True, False):
        expected["--key"] = [set_key0]
    elif set_keys == (True, False, True):
        expected["--key"] = [set_key]

    else:
        raise NotImplementedError

    actual = docoptcfg(docstring, env_prefix="MULTI_")
    assert actual == expected
Example #3
0
def test_no_settable():
    """Test with all options overridden by command line."""
    actual = docoptcfg(DOCSTRING_MULTI, ['1', '--config=config.ini', '--flag', '--key=val'], env_prefix='MULTI_')
    expected = EXPECTED_MULTI.copy()
    expected['--config'] = 'config.ini'
    expected['--flag'] = 1
    expected['--key'] = ['val']
    assert actual == expected
Example #4
0
def test_override(tmpdir, short, equals):
    """Test overriding config values with command line.

    :param tmpdir: pytest fixture.
    :param bool short: Use short arg names.
    :param bool equals: Use ['--key=val'] or ['-kval'] instead of ['--key', 'val'].
    """
    config_file = tmpdir.join('config.ini')
    config_file.write(
        dedent("""\
    [FlashAirMusic]
    ffmpeg-bin=/tmp/ffmpeg
    verbose=false
    """))

    if equals and short:
        argv = ['run', '-c', str(config_file), '-f/tmp/arg/ffmpeg', '-v']
    elif equals:
        argv = [
            'run', '-c',
            str(config_file), '--ffmpeg-bin=/tmp/arg/ffmpeg', '--verbose'
        ]
    else:
        argv = [
            'run', '-c',
            str(config_file), '--ffmpeg-bin', '/tmp/arg/ffmpeg', '--verbose'
        ]

    actual = docoptcfg(DOCSTRING_FAM, argv, config_option='--config')
    expected = EXPECTED_FAM.copy()
    expected['--config'] = str(config_file)
    expected['--ffmpeg-bin'] = '/tmp/arg/ffmpeg'
    expected['--verbose'] = True
    assert actual == expected

    actual = docoptcfg(DOCSTRING_FAM,
                       ['run', '-c', str(config_file)],
                       config_option='--config')
    expected = EXPECTED_FAM.copy()
    expected['--config'] = str(config_file)
    expected['--ffmpeg-bin'] = '/tmp/ffmpeg'
    expected['--verbose'] = False
    assert actual == expected
Example #5
0
def test_docopt_default(monkeypatch, short):
    """Test compatibility with "default" feature in docopt.

    :param monkeypatch: pytest fixture.
    :param bool short: Use short arg names.
    """
    monkeypatch.setenv("FAM_THREADS", "2")

    # Test override.
    actual = docoptcfg(DOCSTRING_FAM, ["run", "-t" if short else "--threads", "1"], env_prefix="FAM_")
    expected = EXPECTED_FAM.copy()
    expected["--threads"] = "1"
    assert actual == expected

    # Test "default".
    actual = docoptcfg(DOCSTRING_FAM, ["run"], env_prefix="FAM_")
    expected = EXPECTED_FAM.copy()
    expected["--threads"] = "2"
    assert actual == expected
Example #6
0
def test_docopt_default(monkeypatch, short):
    """Test compatibility with "default" feature in docopt.

    :param monkeypatch: pytest fixture.
    :param bool short: Use short arg names.
    """
    monkeypatch.setenv('FAM_THREADS', '2')

    # Test override.
    actual = docoptcfg(DOCSTRING_FAM,
                       ['run', '-t' if short else '--threads', '1'],
                       env_prefix='FAM_')
    expected = EXPECTED_FAM.copy()
    expected['--threads'] = '1'
    assert actual == expected

    # Test "default".
    actual = docoptcfg(DOCSTRING_FAM, ['run'], env_prefix='FAM_')
    expected = EXPECTED_FAM.copy()
    expected['--threads'] = '2'
    assert actual == expected
Example #7
0
def test_fam(monkeypatch, tmpdir):
    """Make sure config file and environment variables aren't being handled.

    :param monkeypatch: pytest fixture.
    :param tmpdir: pytest fixture.
    """
    monkeypatch.setenv('FFMPEG_BIN', tmpdir.ensure('ffmpeg'))
    tmpdir.join('config.ini').write('[FlashAirMusic]\nmac-addr = 00:11:22:33:44:55')

    actual = docoptcfg(DOCSTRING_FAM, ['run', '--config', str(tmpdir.join('config.ini'))])
    expected = EXPECTED_FAM.copy()
    expected['--config'] = str(tmpdir.join('config.ini'))

    assert actual == expected
Example #8
0
def test_multi(monkeypatch, tmpdir):
    """Same with multi options.

    :param monkeypatch: pytest fixture.
    :param tmpdir: pytest fixture.
    """
    monkeypatch.setenv('FFMPEG_BIN', tmpdir.ensure('ffmpeg'))
    tmpdir.join('config.ini').write('[my_script]\nkey = \n    val1,\n    val2')

    actual = docoptcfg(DOCSTRING_MULTI, ['1', '--config', str(tmpdir.join('config.ini'))])
    expected = EXPECTED_MULTI.copy()
    expected['--config'] = str(tmpdir.join('config.ini'))

    assert actual == expected
Example #9
0
def test_multi_a_lot(monkeypatch):
    """Test setting >99 env variables. For branch coverage.

    :param monkeypatch: pytest fixture.
    """
    expected = EXPECTED_MULTI.copy()
    monkeypatch.setenv("MULTI_FLAG", "1")  # Ignore.
    for i in range(100):
        monkeypatch.setenv("MULTI_KEY{0}".format(i), str(i))
        if i < 99:
            expected["--key"].append(str(i))
    actual = docoptcfg(DOCSTRING_MULTI, ["1"], ignore=("-h", "-V", "--flag"), env_prefix="MULTI_")
    assert actual == expected
    assert "MULTI_KEY99" in os.environ
    assert "99" not in actual["--key"]
Example #10
0
def test_data_types(monkeypatch, tmpdir, source, data_type):
    """Ensure all sources produce the exact same non-boolean data types and values.

    :param monkeypatch: pytest fixture.
    :param tmpdir: pytest fixture.
    :param source: Config source to test.
    :param data_type: Data type to test.
    """
    argv = ["run"]
    expected = EXPECTED_FAM.copy()

    if source == "file":
        config_file = tmpdir.join("config.ini")
        if data_type == "str":
            config_file.write("[FlashAirMusic]\nmac-addr = one")
        elif data_type == "int":
            config_file.write("[FlashAirMusic]\nmac-addr = 1")
        else:
            config_file.write("[FlashAirMusic]\nmac-addr = 2.3")
        monkeypatch.setenv("FAM_CONFIG", str(config_file))
        expected["--config"] = str(config_file)

    elif source == "env":
        if data_type == "str":
            monkeypatch.setenv("FAM_MAC_ADDR", "one")
        elif data_type == "int":
            monkeypatch.setenv("FAM_MAC_ADDR", "1")
        else:
            monkeypatch.setenv("FAM_MAC_ADDR", "2.3")

    else:
        if data_type == "str":
            argv.extend(["--mac-addr", "one"])
        elif data_type == "int":
            argv.extend(["--mac-addr", "1"])
        else:
            argv.extend(["--mac-addr", "2.3"])

    # Set expected.
    if data_type == "str":
        expected["--mac-addr"] = "one"
    elif data_type == "int":
        expected["--mac-addr"] = "1"
    else:
        expected["--mac-addr"] = "2.3"

    actual = docoptcfg(DOCSTRING_FAM, argv, config_option="-c", env_prefix="FAM_")
    assert actual == expected
Example #11
0
def test_data_types(monkeypatch, tmpdir, source, data_type):
    """Ensure all sources produce the exact same non-boolean data types and values.

    :param monkeypatch: pytest fixture.
    :param tmpdir: pytest fixture.
    :param source: Config source to test.
    :param data_type: Data type to test.
    """
    argv = ['run']
    expected = EXPECTED_FAM.copy()

    if source == 'file':
        config_file = tmpdir.join('config.ini')
        if data_type == 'str':
            config_file.write('[FlashAirMusic]\nmac-addr = one')
        elif data_type == 'int':
            config_file.write('[FlashAirMusic]\nmac-addr = 1')
        else:
            config_file.write('[FlashAirMusic]\nmac-addr = 2.3')
        monkeypatch.setenv('FAM_CONFIG', str(config_file))
        expected['--config'] = str(config_file)

    elif source == 'env':
        if data_type == 'str':
            monkeypatch.setenv('FAM_MAC_ADDR', 'one')
        elif data_type == 'int':
            monkeypatch.setenv('FAM_MAC_ADDR', '1')
        else:
            monkeypatch.setenv('FAM_MAC_ADDR', '2.3')

    else:
        if data_type == 'str':
            argv.extend(['--mac-addr', 'one'])
        elif data_type == 'int':
            argv.extend(['--mac-addr', '1'])
        else:
            argv.extend(['--mac-addr', '2.3'])

    # Set expected.
    if data_type == 'str':
        expected['--mac-addr'] = 'one'
    elif data_type == 'int':
        expected['--mac-addr'] = '1'
    else:
        expected['--mac-addr'] = '2.3'

    actual = docoptcfg(DOCSTRING_FAM, argv, config_option='-c', env_prefix='FAM_')
    assert actual == expected
Example #12
0
def test_multi_a_lot(monkeypatch):
    """Test setting >99 env variables. For branch coverage.

    :param monkeypatch: pytest fixture.
    """
    expected = EXPECTED_MULTI.copy()
    monkeypatch.setenv('MULTI_FLAG', '1')  # Ignore.
    for i in range(100):
        monkeypatch.setenv('MULTI_KEY{0}'.format(i), str(i))
        if i < 99:
            expected['--key'].append(str(i))
    actual = docoptcfg(DOCSTRING_MULTI, ['1'],
                       ignore=('-h', '-V', '--flag'),
                       env_prefix='MULTI_')
    assert actual == expected
    assert 'MULTI_KEY99' in os.environ
    assert '99' not in actual['--key']
Example #13
0
def test_config_file_in_env(monkeypatch, tmpdir):
    """Test specifying a config file using only env variables.

    :param monkeypatch: pytest fixture.
    :param tmpdir: pytest fixture.
    """
    config_file = tmpdir.join('config.ini')
    config_file.write(dedent("""\
    [FlashAirMusic]
    mac-addr = AA:BB:CC:DD:EE:FF
    """))

    monkeypatch.setenv('FAM_CONFIG', str(config_file))
    actual = docoptcfg(DOCSTRING_FAM, ['run'], config_option='-c', env_prefix='FAM_')
    expected = EXPECTED_FAM.copy()
    expected['--config'] = str(config_file)
    expected['--mac-addr'] = 'AA:BB:CC:DD:EE:FF'
    assert actual == expected
Example #14
0
def test_override(monkeypatch, tmpdir, set_arg, set_env, set_file):
    """Test source overrides.

    :param monkeypatch: pytest fixture.
    :param tmpdir: pytest fixture.
    :param bool set_arg: Set value in command line arguments.
    :param bool set_env: Set value in environment variables.
    :param bool set_file: Set value in config file.
    """
    config_file = tmpdir.join("config.ini")
    config_file.write(
        dedent(
            """\
    [FlashAirMusic]
    quiet = true
    {0}
    """
        ).format("ffmpeg-bin = ffmpeg_file" if set_file else "")
    )

    monkeypatch.setenv("FAM_CONFIG", str(config_file))
    monkeypatch.setenv("FAM_VERBOSE", "true")
    if set_env:
        monkeypatch.setenv("FAM_FFMPEG_BIN", "ffmpeg_env")

    argv = ["run", "-m", "00:11:22:33:44:55"] + (["--ffmpeg-bin", "ffmpeg_arg"] if set_arg else [])

    actual = docoptcfg(DOCSTRING_FAM, argv, config_option="-c", env_prefix="FAM_")
    expected = EXPECTED_FAM.copy()
    expected["--config"] = str(config_file)
    expected["--mac-addr"] = "00:11:22:33:44:55"
    expected["--quiet"] = True
    expected["--verbose"] = True

    if set_arg:
        expected["--ffmpeg-bin"] = "ffmpeg_arg"
    elif set_env:
        expected["--ffmpeg-bin"] = "ffmpeg_env"
    elif set_file:
        expected["--ffmpeg-bin"] = "ffmpeg_file"

    assert actual == expected
Example #15
0
def test_config_section_is_missing_from_default_config_file(tmpdir):
    """Test not failing if config section is missing from default config file.

    :param tmpdir: pytest fixture.
    """
    config_file = tmpdir.ensure('config.ini')
    config_file.write(dedent("""\
    [foobar]
    bar=baz
    """))
    config_file_path = str(config_file)
    docstring = DOCSTRING_DEFAULT_CONFIGFILE.replace(
        '/skdjfgksdhfgsdfgjshdf.ini', config_file_path)
    expected = EXPECTED_DEFAULT_CONFIGFILE.copy()
    expected['--config'] = config_file_path
    actual = docoptcfg(docstring,
                       argv=['--foo', 'bar', '1'],
                       ignore_missing_default_config=True,
                       config_option='--config')
    assert actual == expected
Example #16
0
def test(monkeypatch, set_config, set_verbose):
    """Test with env variables.

    :param monkeypatch: pytest fixture.
    :param str set_config: Set FAM_CONFIG to this value if not None.
    :param str set_verbose: Set FAM_VERBOSE to this value if not None.
    """
    monkeypatch.setenv("FAM_HELP", "True")
    monkeypatch.setenv("FAM_VERSION", "True")

    expected = EXPECTED_FAM.copy()
    if set_config is not None:
        expected["--config"] = str(set_config)
        monkeypatch.setenv("FAM_CONFIG", set_config)
    if set_verbose is not None:
        if set_verbose.strip().lower() in ("true", "yes", "on", "1"):
            expected["--verbose"] = True
        monkeypatch.setenv("FAM_VERBOSE", set_verbose)

    actual = docoptcfg(DOCSTRING_FAM, ["run"], env_prefix="FAM_")
    assert actual == expected
Example #17
0
def test(monkeypatch, set_config, set_verbose):
    """Test with env variables.

    :param monkeypatch: pytest fixture.
    :param str set_config: Set FAM_CONFIG to this value if not None.
    :param str set_verbose: Set FAM_VERBOSE to this value if not None.
    """
    monkeypatch.setenv('FAM_HELP', 'True')
    monkeypatch.setenv('FAM_VERSION', 'True')

    expected = EXPECTED_FAM.copy()
    if set_config is not None:
        expected['--config'] = str(set_config)
        monkeypatch.setenv('FAM_CONFIG', set_config)
    if set_verbose is not None:
        if set_verbose.strip().lower() in ('true', 'yes', 'on', '1'):
            expected['--verbose'] = True
        monkeypatch.setenv('FAM_VERBOSE', set_verbose)

    actual = docoptcfg(DOCSTRING_FAM, ['run'], env_prefix='FAM_')
    assert actual == expected
Example #18
0
def test_config_file_in_env(monkeypatch, tmpdir):
    """Test specifying a config file using only env variables.

    :param monkeypatch: pytest fixture.
    :param tmpdir: pytest fixture.
    """
    config_file = tmpdir.join("config.ini")
    config_file.write(
        dedent(
            """\
    [FlashAirMusic]
    mac-addr = AA:BB:CC:DD:EE:FF
    """
        )
    )

    monkeypatch.setenv("FAM_CONFIG", str(config_file))
    actual = docoptcfg(DOCSTRING_FAM, ["run"], config_option="-c", env_prefix="FAM_")
    expected = EXPECTED_FAM.copy()
    expected["--config"] = str(config_file)
    expected["--mac-addr"] = "AA:BB:CC:DD:EE:FF"
    assert actual == expected
Example #19
0
def test_override(monkeypatch, tmpdir, set_arg, set_env, set_file):
    """Test source overrides.

    :param monkeypatch: pytest fixture.
    :param tmpdir: pytest fixture.
    :param bool set_arg: Set value in command line arguments.
    :param bool set_env: Set value in environment variables.
    :param bool set_file: Set value in config file.
    """
    config_file = tmpdir.join('config.ini')
    config_file.write(dedent("""\
    [FlashAirMusic]
    quiet = true
    {0}
    """).format('ffmpeg-bin = ffmpeg_file' if set_file else ''))

    monkeypatch.setenv('FAM_CONFIG', str(config_file))
    monkeypatch.setenv('FAM_VERBOSE', 'true')
    if set_env:
        monkeypatch.setenv('FAM_FFMPEG_BIN', 'ffmpeg_env')

    argv = ['run', '-m', '00:11:22:33:44:55'] + (['--ffmpeg-bin', 'ffmpeg_arg'] if set_arg else [])

    actual = docoptcfg(DOCSTRING_FAM, argv, config_option='-c', env_prefix='FAM_')
    expected = EXPECTED_FAM.copy()
    expected['--config'] = str(config_file)
    expected['--mac-addr'] = '00:11:22:33:44:55'
    expected['--quiet'] = True
    expected['--verbose'] = True

    if set_arg:
        expected['--ffmpeg-bin'] = 'ffmpeg_arg'
    elif set_env:
        expected['--ffmpeg-bin'] = 'ffmpeg_env'
    elif set_file:
        expected['--ffmpeg-bin'] = 'ffmpeg_file'

    assert actual == expected
Example #20
0
def test_multi_flag(monkeypatch, multi, set_flag):
    """Test with repeatable flag/boolean option.

    :param monkeypatch: pytest fixture.
    :param bool multi: Test with ... and without ... in docstring.
    :param str set_flag: Set MULTI_FLAG to this value if not None.
    """
    monkeypatch.setattr("sys.argv", ["pytest", "1"])
    docstring = DOCSTRING_MULTI if multi else DOCSTRING_NOT_MULTI
    expected = EXPECTED_MULTI.copy() if multi else EXPECTED_NOT_MULTI.copy()

    if set_flag is not None:
        monkeypatch.setenv("MULTI_FLAG", set_flag)
        if not multi and set_flag == "1":
            expected["--flag"] = True
        elif not multi:
            expected["--flag"] = False
        elif set_flag.isdigit():
            expected["--flag"] = int(set_flag)
        else:
            expected["--flag"] = 0

    actual = docoptcfg(docstring, env_prefix="MULTI_")
    assert actual == expected
Example #21
0
def test_multi_flag(monkeypatch, multi, set_flag):
    """Test with repeatable flag/boolean option.

    :param monkeypatch: pytest fixture.
    :param bool multi: Test with ... and without ... in docstring.
    :param str set_flag: Set MULTI_FLAG to this value if not None.
    """
    monkeypatch.setattr('sys.argv', ['pytest', '1'])
    docstring = DOCSTRING_MULTI if multi else DOCSTRING_NOT_MULTI
    expected = EXPECTED_MULTI.copy() if multi else EXPECTED_NOT_MULTI.copy()

    if set_flag is not None:
        monkeypatch.setenv('MULTI_FLAG', set_flag)
        if not multi and set_flag == '1':
            expected['--flag'] = True
        elif not multi:
            expected['--flag'] = False
        elif set_flag.isdigit():
            expected['--flag'] = int(set_flag)
        else:
            expected['--flag'] = 0

    actual = docoptcfg(docstring, env_prefix='MULTI_')
    assert actual == expected
def main():
    arguments = docoptcfg(__doc__, env_prefix='GITLAB_')
    gitlab_token = arguments.get('--token')
    gitlab_group = arguments.get('--group')
    gitlab_config = arguments.get('--config')
    gitlab_host = arguments.get('--host')
    gitlab_server = arguments.get('--server')
    dry_run = arguments.get('--dry-run')
    verbose = arguments.get('--verbose')
    logging.basicConfig(level=(50 - verbose*10))

    config = toml.load(gitlab_config)

    if gitlab_server is None:
        gitlab_server = config['gitlab_admin']['default_server']
    if gitlab_host is None:
        gitlab_host = config['servers'][gitlab_server]['host']
    if gitlab_token is None:
        gitlab_token = config['servers'][gitlab_server]['token']
    if gitlab_group is None:
        gitlab_group = config['gitlab_admin']['default_group']

    assert gitlab_host, "GITLAB_HOST not defined, export an ENV var or pass command line argument"
    assert gitlab_token, "GITLAB_TOKEN not defined, export an ENV var or pass command line argument"
    assert gitlab_group, "GITLAB_GROUP not defined, export an ENV var or pass command line argument"

    gl = gitlab.Gitlab('https://' + gitlab_host, gitlab_token, api_version=4, ssl_verify=SSL_VERIFY)
    group = gl.groups.get(gitlab_group)
    all_groups = gl.groups.list(all=True)
    sub_groups = recurse_subgroups(all_groups, group)

    for sg in sub_groups:
        for project in sg.projects.list():
            apply_rules(project, config)
    for project in group.projects.list():
        apply_rules(project, config, dry_run)
Example #23
0
                      for project in project_list]

        project_zone_list = [
            (project_name, zone, cache_dir, refresh_cache)
            for project_name, zone_list in pool_workers.map_async(
                get_project_zone_list, param_list).get(timeout)
            for zone in zone_list
        ]

    instance_list = []

    for project_zone_instances in pool_workers.map_async(
            get_project_zone_instances, project_zone_list).get(timeout):
        instance_list.extend(project_zone_instances)

    inventory_json = get_inventory(instance_list)
    print(json.dumps(inventory_json, sort_keys=True, indent=2))


if __name__ == "__main__":
    log.basicConfig(filename='gce_googleapiclient.log', level=log.ERROR)
    try:
        ARGS = docoptcfg(__doc__,
                         config_option='--config',
                         env_prefix=ENV_PREFIX)
    except DocoptcfgFileError as exc:
        log.info('Failed reading: %s', str(exc))
        ARGS = docoptcfg(__doc__, env_prefix=ENV_PREFIX)

    main(ARGS)
def main():
    args = docoptcfg(__doc__, env_prefix="SLACKEMAILDIGEST_", config_option='--config')

    # process args
    tz_str = args['--timezone']
    tz = pytz.timezone(tz_str)

    # for date, make naive timetuples, use calendar.timegm to convert them to
    # the proper timestamps (which are always UTC)
    if args['--date']:
        date = datetime.datetime.strptime(args['--date'], '%Y-%m-%d')
        date = tz.localize(date)
    else:
        now_utc = pytz.utc.localize(datetime.datetime.utcfromtimestamp(time.time()))
        now_tz = now_utc.astimezone(tz)
        yesterday_tz = now_tz - datetime.timedelta(days=1)
        date = yesterday_tz.replace(hour=0, minute=0, second=0, microsecond=0)

    start_ts = calendar.timegm(date.utctimetuple())
    end_ts = calendar.timegm((date + datetime.timedelta(days=1)).utctimetuple())

    # work-around docoptcfg not taking required arguments from a config file
    for required in ['--token', '--from', '--to']:
        if not args[required]:
            sys.exit("Must provide {}".format(required))

    token = args['--token']
    verbose = args['--verbose']
    delivery = args['--delivery']
    from_email = args['--from']
    to = args['--to']
    from_name = args['--from-name']
    delay = int(args['--delay'])
    slack_channel = args['--channel']
    invite_link = args['--invite-link']

    if delivery not in delivery_methods:
        sys.exit("Unknown delivery method: %s" % (delivery,))

    # scrape
    print("Fetching Slack messages for #%s from %s (%s) to %s (%s) " % (
        slack_channel,
        pytz.utc.localize(datetime.datetime.utcfromtimestamp(start_ts)).astimezone(tz),
        pytz.utc.localize(datetime.datetime.utcfromtimestamp(start_ts)).astimezone(tz).strftime("%Z"),
        pytz.utc.localize(datetime.datetime.utcfromtimestamp(end_ts)).astimezone(tz),
        pytz.utc.localize(datetime.datetime.utcfromtimestamp(end_ts)).astimezone(tz).strftime("%Z"),
        ), file=sys.stderr)

    scraper = SlackScraper(token, verbose=verbose)
    scraper.set_invite_link(invite_link)
    team_id = scraper.get_team_id()
    channel_id = scraper.get_channel_id(slack_channel)

    hist = scraper.get_channel_history(
        slack_channel,
        oldest=start_ts, latest=end_ts,
    )

    hist.sort(key=lambda msg: float(msg['ts']))

    html_renderer = HTMLRenderer(scraper, tz)
    email_renderer = EmailRenderer(html_renderer)

    # render emails, replying to the last day's digest, and setting the last
    # id to be reply-able from the next day's digest
    emails = email_renderer.render_digest_emails(
        hist, date, team_id, channel_id,
    )
    for email in emails:
        email['sender'] = ("%s <%s>" % (from_name, from_email)) if from_name else from_email
        email['to'] = to

    delivery_method = delivery_methods[delivery]
    print("Delivering in %d parts... via %s" % (len(emails), delivery_method.__name__), file=sys.stderr)
    
    for email in emails:    
        delivery_method(args, email)
        for _ in progress.bar(range(delay), label="Waiting to send next message... "):
            time.sleep(1)
Example #25
0
def test_none():
    """Test when user doesn't specify a config file."""
    expected = EXPECTED_FAM.copy()
    actual = docoptcfg(DOCSTRING_FAM, ['run'], config_option='--config')
    assert actual == expected
Example #26
0
def main():
    args = docoptcfg(__doc__,
                     env_prefix="SLACKEMAILDIGEST_",
                     config_option='--config')

    # process args
    tz_str = args['--timezone']
    tz = pytz.timezone(tz_str)

    # for date, make naive timetuples, use calendar.timegm to convert them to
    # the proper timestamps (which are always UTC)
    if args['--date']:
        date = datetime.datetime.strptime(args['--date'], '%Y-%m-%d')
        date = tz.localize(date)
    else:
        now_utc = pytz.utc.localize(
            datetime.datetime.utcfromtimestamp(time.time()))
        now_tz = now_utc.astimezone(tz)
        yesterday_tz = now_tz - datetime.timedelta(days=1)
        date = yesterday_tz.replace(hour=0, minute=0, second=0, microsecond=0)

    start_ts = calendar.timegm(date.utctimetuple())
    end_ts = calendar.timegm(
        (date + datetime.timedelta(days=1)).utctimetuple())

    # work-around docoptcfg not taking required arguments from a config file
    for required in ['--token', '--from', '--to']:
        if not args[required]:
            sys.exit("Must provide {}".format(required))

    token = args['--token']
    verbose = args['--verbose']
    delivery = args['--delivery']
    from_email = args['--from']
    to = args['--to']
    from_name = args['--from-name']
    delay = int(args['--delay'])
    slack_channel = args['--channel']
    invite_link = args['--invite-link']

    if delivery not in delivery_methods:
        sys.exit("Unknown delivery method: %s" % (delivery, ))

    # scrape
    print("Fetching Slack messages for #%s from %s (%s) to %s (%s) " % (
        slack_channel,
        pytz.utc.localize(
            datetime.datetime.utcfromtimestamp(start_ts)).astimezone(tz),
        pytz.utc.localize(datetime.datetime.utcfromtimestamp(
            start_ts)).astimezone(tz).strftime("%Z"),
        pytz.utc.localize(
            datetime.datetime.utcfromtimestamp(end_ts)).astimezone(tz),
        pytz.utc.localize(datetime.datetime.utcfromtimestamp(
            end_ts)).astimezone(tz).strftime("%Z"),
    ),
          file=sys.stderr)

    scraper = SlackScraper(token, verbose=verbose)
    scraper.set_invite_link(invite_link)
    team_id = scraper.get_team_id()
    channel_id = scraper.get_channel_id(slack_channel)

    hist = scraper.get_channel_history(
        slack_channel,
        oldest=start_ts,
        latest=end_ts,
    )

    hist.sort(key=lambda msg: float(msg['ts']))

    html_renderer = HTMLRenderer(scraper, tz)
    email_renderer = EmailRenderer(html_renderer)

    # render emails, replying to the last day's digest, and setting the last
    # id to be reply-able from the next day's digest
    emails = email_renderer.render_digest_emails(
        hist,
        date,
        team_id,
        channel_id,
    )
    for email in emails:
        email['sender'] = (
            "%s <%s>" % (from_name, from_email)) if from_name else from_email
        email['to'] = to

    delivery_method = delivery_methods[delivery]
    print("Delivering in %d parts... via %s" %
          (len(emails), delivery_method.__name__),
          file=sys.stderr)

    for email in emails:
        delivery_method(args, email)
        for _ in progress.bar(range(delay),
                              label="Waiting to send next message... "):
            time.sleep(1)
Example #27
0
def test_errors(tmpdir):
    """Test error handling.

    :param tmpdir: pytest fixture.
    """
    config_file = tmpdir.join('config.ini')
    argv = ['run', '-c', str(config_file)]

    # Test bad config_option value.
    with pytest.raises(DocoptcfgError):
        docoptcfg(DOCSTRING_FAM, argv, config_option='--config-file')

    # Test missing file.
    with pytest.raises(DocoptcfgFileError) as exc:
        docoptcfg(DOCSTRING_FAM, argv, config_option='-c')
    assert exc.value.message == 'Unable to read config file.'
    assert exc.value.FILE_PATH == str(config_file)
    assert 'No such file or directory' in exc.value.original_error

    # Test permission error.
    if os.name != 'nt':
        config_file.ensure().chmod(0o0244)
        with pytest.raises(DocoptcfgFileError) as exc:
            docoptcfg(DOCSTRING_FAM, argv, config_option='-c')
        assert exc.value.message == 'Unable to read config file.'
        assert exc.value.FILE_PATH == str(config_file)
        assert 'Permission denied' in exc.value.original_error

    # Test empty file.
    config_file.ensure().chmod(0o0644)
    with pytest.raises(DocoptcfgFileError) as exc:
        docoptcfg(DOCSTRING_FAM, argv, config_option='-c')
    assert exc.value.message == 'Section [FlashAirMusic] not in config file.'
    assert exc.value.FILE_PATH == str(config_file)
    assert exc.value.original_error is None

    # Test corrupt file.
    config_file.write('\x00\x00\x00\x00')
    with pytest.raises(DocoptcfgFileError) as exc:
        docoptcfg(DOCSTRING_FAM, argv, config_option='-c')
    assert exc.value.message == 'Unable to parse config file.'
    assert exc.value.FILE_PATH == str(config_file)
    assert 'File contains no section headers.' in exc.value.original_error

    # Test bad boolean.
    config_file.write('[FlashAirMusic]\nverbose = "test"')
    with pytest.raises(DocoptcfgFileError) as exc:
        docoptcfg(DOCSTRING_FAM, argv, config_option='-c')
    assert exc.value.message == 'Boolean option "verbose" invalid.'
    assert exc.value.FILE_PATH == str(config_file)
    assert 'Not a boolean' in exc.value.original_error