diff --git a/slack_deleter/delete_batch.py b/slack_deleter/delete_batch.py index de280bd..de25007 100644 --- a/slack_deleter/delete_batch.py +++ b/slack_deleter/delete_batch.py @@ -2,9 +2,7 @@ import os import time -import slack - -from .env import env_str +from .utils import get_client, normalize_timestamp class BatchDeleter: @@ -14,7 +12,7 @@ def cli(self, argv, prog=None): description='Delete messages from a list of timestamp IDs. Replies are also deleted.' ) parser.add_argument('channel', help='Channel ID') - parser.add_argument('ts', nargs='+', help='Timestamps of messages') + parser.add_argument('ts', nargs='+', help='Timestamps of messages (format: 1586185432.000100 or 1586185432000100 or p1586185432000100)') args = parser.parse_args(argv) delete_count = self.run(args) @@ -24,10 +22,11 @@ def cli(self, argv, prog=None): print('No messages found') def run(self, args): - client = slack.WebClient(token=env_str('SLACK_TOKEN')) + client = get_client() response = client.conversations_history(channel=args.channel, limit=1000) + ts = [normalize_timestamp(t) for t in args.ts] matches = [ - msg for msg in response.data['messages'] if msg['ts'] in args.ts + msg for msg in response.data['messages'] if msg['ts'] in ts ] delete_count = 0 diff --git a/slack_deleter/delete_between.py b/slack_deleter/delete_between.py index a84c869..e4978c4 100644 --- a/slack_deleter/delete_between.py +++ b/slack_deleter/delete_between.py @@ -2,9 +2,7 @@ import os import time -import slack - -from .env import env_str +from .utils import get_client, normalize_timestamp class BetweenDeleter: @@ -16,7 +14,7 @@ def cli(self, argv, prog=None): 'based on the parent timestamps.' ) parser.add_argument('channel', help='Channel ID') - parser.add_argument('--from_ts', help='First timestamp to delete', default='0000000000.000000') + parser.add_argument('--from_ts', help='First timestamp to delete (format: 1586185432.000100 or 1586185432000100 or p1586185432000100)', default='0000000000.000000') parser.add_argument('--until_ts', help='Last timestamp to delete', default='9999999999.999999') args = parser.parse_args(argv) @@ -27,10 +25,12 @@ def cli(self, argv, prog=None): print(f'No messages found') def run(self, args): - client = slack.WebClient(token=env_str('SLACK_TOKEN')) + client = get_client() response = client.conversations_history(channel=args.channel, limit=1000) + from_ts = normalize_timestamp(args.from_ts) + until_ts = normalize_timestamp(args.until_ts) matches = [ - msg for msg in response.data['messages'] if args.from_ts <= msg['ts'] <= args.until_ts + msg for msg in response.data['messages'] if from_ts <= msg['ts'] <= until_ts ] delete_count = 0 diff --git a/slack_deleter/env.py b/slack_deleter/env.py index 723ae46..0b9e249 100644 --- a/slack_deleter/env.py +++ b/slack_deleter/env.py @@ -6,11 +6,12 @@ ''' import os +from pathlib import Path __all__ = ['BASE_DIR', 'abs_path', 'env_bool', 'env_str', 'env_list'] -BASE_DIR = os.path.dirname(__file__) +ENV_PATH = Path(__file__).parent.parent / '.env' def env_setting(key, default): @@ -18,11 +19,6 @@ def env_setting(key, default): return os.environ.get(key, default) -def abs_path(*args): - '''Transforms relative path from `args` to absolute path, based on project root directory''' - return os.path.join(BASE_DIR, *args) - - def env_bool(name, default=False): ''' Get a boolean value from environment variable. @@ -75,7 +71,7 @@ def env_list(name, separator=',', default=None): def _load_env_file(): - envfile = abs_path('.env') + envfile = ENV_PATH.resolve() if os.path.isfile(envfile): with open(envfile, 'r', encoding='utf-8') as fp: for line in fp: @@ -87,3 +83,4 @@ def _load_env_file(): _load_env_file() + diff --git a/slack_deleter/utils.py b/slack_deleter/utils.py new file mode 100644 index 0000000..acca363 --- /dev/null +++ b/slack_deleter/utils.py @@ -0,0 +1,26 @@ +import time + +import slack + +from .env import env_str + + +def get_client(): + token = env_str('SLACK_TOKEN') + client = slack.WebClient(token=token) + return client + +def normalize_timestamp(ts): + """ + Normalize Slack message timestamp. + + Removes 'p' prefix and adds decimal separator if needed. + """ + ts = str(ts) + if ts[0] == 'p': + ts = ts[1:] + if '.' not in ts: + ts = ts[:-6] + '.' + ts[-6:] + + return ts +