1
0
mirror of https://github.com/gryf/slack-backup.git synced 2025-12-17 11:30:25 +01:00

Added config file

This commit is contained in:
2016-11-27 20:39:20 +01:00
parent b5e9c150ed
commit c1c4581248
3 changed files with 274 additions and 19 deletions

View File

@@ -7,6 +7,7 @@ import argparse
import logging import logging
from slack_backup import client from slack_backup import client
from slack_backup import config
def setup_logger(args): def setup_logger(args):
@@ -47,60 +48,73 @@ def main():
fetch = subparser.add_parser('fetch', help='Update local db with Slack' fetch = subparser.add_parser('fetch', help='Update local db with Slack'
' data') ' data')
fetch.add_argument('-t', '--token', required=True, help='Slack token - ' fetch.add_argument('-t', '--token', default=None, help='Slack token - '
'a string, which can be generated/obtained via ' 'a string, which can be generated/obtained via '
'https://api.slack.com/docs/oauth-test-tokens page.') 'https://api.slack.com/docs/oauth-test-tokens page.')
fetch.add_argument('-u', '--user', default='', help='Username for your ' fetch.add_argument('-u', '--user', default=None, help='Username for your '
'Slack account') 'Slack account')
fetch.add_argument('-p', '--password', default='', help='Password for your ' fetch.add_argument('-p', '--password', default=None, help='Password for '
'Slack account.') 'your Slack account.')
fetch.add_argument('-e', '--team', required=True, help='Team name, which ' fetch.add_argument('-e', '--team', default=None, help='Team name, which '
'is part of slack url, for example: if url is ' 'is part of slack url, for example: if url is '
'"https://team.slack.com" than "team" is a name of ' '"https://team.slack.com" than "team" is a name of '
'the team.') 'the team.')
fetch.add_argument('-v', '--verbose', help='Be verbose. Adding more "v"' fetch.add_argument('-v', '--verbose', help='Be verbose. Adding more "v" '
'will increase verbosity', action="count", default=0) 'will increase verbosity', action="count",
fetch.add_argument('-q', '--quiet', help='Be quiet. Adding more "q"' default=None)
'will decrease verbosity', action="count", default=0) fetch.add_argument('-q', '--quiet', help='Be quiet. Adding more "q" will'
fetch.add_argument('-c', '--channels', default=[], nargs='+', ' decrease verbosity', action="count", default=None)
fetch.add_argument('-c', '--channels', default=None, nargs='+',
help='List of channels to perform actions on. ' help='List of channels to perform actions on. '
'Default is all channels.') 'Default is all channels.')
fetch.add_argument('-d', '--database', default='', fetch.add_argument('-d', '--database', default=None,
help='Path to the database file.') help='Path to the database file.')
fetch.add_argument('-i', '--config', default=None,
help='Use specific config file.')
fetch.set_defaults(func=fetch_data) fetch.set_defaults(func=fetch_data)
generate = subparser.add_parser('generate', help='Generate logs out of ' generate = subparser.add_parser('generate', help='Generate logs out of '
'data in provided database') 'data in provided database')
generate.add_argument('-o', '--output', default='logs', help="Output " generate.add_argument('-o', '--output', default=None, help="Output "
"directory for store logs. All logs are organised " "directory for store logs. All logs are organised "
"per channel. By default it's `logs' directory") "per channel. By default it's `logs' directory")
generate.add_argument('-f', '--format', default='none', generate.add_argument('-f', '--format', default=None,
choices=('text', 'none'), choices=('text', 'none'),
help='Output format. Default is none; only database ' help='Output format. Default is none; only database '
'is updated by latest messages for all/selected ' 'is updated by latest messages for all/selected '
'channels.') 'channels.')
generate.add_argument('-t', '--theme', default='plain', generate.add_argument('-t', '--theme', default=None,
choices=('plain', 'unicode'), choices=('plain', 'unicode'),
help='Choose theme for text output. It doesn\'t ' help='Choose theme for text output. It doesn\'t '
'affect other output formats.') 'affect other output formats.')
generate.add_argument('-v', '--verbose', help='Be verbose. Adding more "v"' generate.add_argument('-v', '--verbose', help='Be verbose. Adding more '
'will increase verbosity', action="count", default=0) '"v" will increase verbosity', action="count",
generate.add_argument('-q', '--quiet', help='Be quiet. Adding more "q"' default=None)
'will decrease verbosity', action="count", default=0) generate.add_argument('-q', '--quiet', help='Be quiet. Adding more "q" '
'will decrease verbosity', action="count",
default=None)
generate.add_argument('-c', '--channels', default=[], nargs='+', generate.add_argument('-c', '--channels', default=[], nargs='+',
help='List of channels to perform actions on. ' help='List of channels to perform actions on. '
'Default is all channels.') 'Default is all channels.')
generate.add_argument('-d', '--database', default='', generate.add_argument('-d', '--database', default=None,
help='Path to the database file.') help='Path to the database file.')
generate.add_argument('-i', '--config', default=None,
help='Use specific config file.')
generate.set_defaults(func=generate_raport) generate.set_defaults(func=generate_raport)
args = parser.parse_args() args = parser.parse_args()
cfg = config.Config()
msg = cfg.update(args)
setup_logger(args) setup_logger(args)
logging.info(msg)
args.func(args) args.func(args)

107
slack_backup/config.py Normal file
View File

@@ -0,0 +1,107 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Configuration module for slack-backup
"""
import json
import os
import configparser
class Config(object):
"""Configuration keeper"""
ints = ['verbose', 'quiet']
sections = {'common': ['channels', 'database', 'quiet', 'verbose'],
'fetch': ['user', 'password', 'team', 'token'],
'generate': ['output', 'format', 'theme']}
def __init__(self):
"""
Init. Read config, if exists, and update passed argument parser
object.
"""
self.cp = configparser.ConfigParser()
self._options = {'channels': [],
'database': None,
'quiet': 0,
'verbose': 0,
'user': None,
'password': None,
'team': None,
'token': None,
'output': None,
'format': None,
'theme': None}
# This message supposed to be displayed in INFO level. During the time
# of running the code where it should be displayed there is no
# complete information about logging level. Displaying message is
# dependent on the a) config file, b) argument from commandline. Let's
# resolve if user want to have that information or not after merging
# those two sources. If user do not want to see any message in INFO
# level, we shouldn't do so.
self.msg = ''
def update(self, args):
self.load_config(args)
self.parse_loaded_options()
self.update_args(args)
return self.msg
def load_config(self, args):
if not args.config:
path = os.path.join(os.path.abspath('.'), 'slack-backup.ini')
else:
path = args.config
locations = [path,
'./slack-backup.conf',
os.path.expandvars('$XDG_CONFIG_HOME/slack-backup.ini'),
os.path.expandvars('$HOME/.config/slack-backup.ini')]
for location in locations:
if os.path.exists(location):
self.cp.read(location)
self.msg = 'Found configuration file: %s' % location
break
else:
self.msg = 'No configuration file found'
def parse_loaded_options(self):
for section in self.cp.sections():
if section not in self.sections:
continue
for option in self.sections[section]:
if option in self.ints:
val = self.cp.getint(section, option, fallback=0)
elif option == 'channels':
val = self.cp.get(section, option, fallback='[]')
val = json.loads(val)
else:
val = self.cp.get(section, option, fallback='')
self._options[option] = val
def update_args(self, args):
# special case, re-set information for verbose/quiet options
if args.verbose is not None and self._options['quiet'] is not None:
self._options['quiet'] = 0
self._options['verbose'] = args.verbose
if args.quiet is not None and self._options['verbose'] is not None:
self._options['verbose'] = 0
self._options['quiet'] = args.quiet
for sec_id in (args.parser, 'common'):
for option in self.sections[sec_id]:
if option in args:
if getattr(args, option) is not None:
continue
setattr(args, option, self._options[option])

134
tests/test_config.py Normal file
View File

@@ -0,0 +1,134 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import tempfile
import os
import unittest
from slack_backup import config
CONF = """\
[common]
channels=["one","two", "three"]
database=dbfname.sqlite
quiet=1
verbose=2
[generate]
output=logs
format=text
theme=plain
[fetch]
user=someuser@address.com
password=secret
team=myteam
token=xxxx-1111111111-222222222222-333333333333-r4nd0ms7uff
"""
class TestConfig(unittest.TestCase):
def setUp(self):
fd, self.confname = tempfile.mkstemp()
os.close(fd)
with open(self.confname, 'w') as fobj:
fobj.write(CONF)
def tearDown(self):
os.unlink(self.confname)
def test_config(self):
self.assertTrue(os.path.exists(self.confname))
self.assertTrue(os.path.isfile(self.confname))
args = argparse.Namespace()
args.config = None
args.parser = 'fetch'
args.verbose = 2
args.quiet = None
args.channels = None
args.database = None
args.user = None
args.password = None
args.team = None
args.token = None
conf = config.Config()
conf.update(args)
self.assertDictEqual(vars(args), {'config': None,
'parser': 'fetch',
'verbose': 2,
'quiet': 0,
'channels': [],
'database': '',
'user': None,
'password': None,
'team': None,
'token': None})
args = argparse.Namespace()
args.config = self.confname
args.parser = 'fetch'
args.verbose = 2
args.quiet = None
args.channels = None
args.database = None
args.user = None
args.password = None
args.team = None
args.token = None
conf = config.Config()
conf.update(args)
self.assertEqual(conf._options['verbose'], 2)
self.assertListEqual(conf._options['channels'],
['one', 'two', 'three'])
self.assertEqual(conf._options['database'], 'dbfname.sqlite')
self.assertEqual(conf._options['user'], 'someuser@address.com')
self.assertDictEqual(vars(args), {'config': self.confname,
'parser': 'fetch',
'verbose': 2,
'quiet': 0,
'channels': ['one', 'two', 'three'],
'database': 'dbfname.sqlite',
'user': 'someuser@address.com',
'password': 'secret',
'team': 'myteam',
'token': 'xxxx-1111111111-'
'222222222222-333333333333-'
'r4nd0ms7uff'})
# override some conf options with commandline
args = argparse.Namespace()
args.config = self.confname
args.parser = 'fetch'
args.verbose = None
args.quiet = 2
args.channels = ['foo']
args.database = None
args.user = 'joe'
args.password = 'ultricies'
args.team = ''
args.token = 'the token'
conf = config.Config()
conf.update(args)
self.assertDictEqual(vars(args), {'config': self.confname,
'parser': 'fetch',
'verbose': 0,
'quiet': 2,
'channels': ['foo'],
'database': 'dbfname.sqlite',
'user': 'joe',
'password': 'ultricies',
'team': '',
'token': 'the token'})