1
0
mirror of https://github.com/gryf/slack-backup.git synced 2025-12-17 19:40:21 +01:00

Added retry mechanism for getting assets

This commit is contained in:
2017-11-01 18:38:31 +01:00
parent ce2888d441
commit a077317cb4

View File

@@ -2,6 +2,7 @@
Module for download files, store them in local filesystem and convert the URLs Module for download files, store them in local filesystem and convert the URLs
to local ones, so that sophisticated writers can make a use of it to local ones, so that sophisticated writers can make a use of it
""" """
import functools
import logging import logging
import os import os
@@ -10,6 +11,35 @@ import requests
from slack_backup import utils from slack_backup import utils
def retry(count):
"""
Decorator for a case, when there is some network hiccup, or slack servers
are too busy to respond or on connection timeout. Parameter count says how
many times it should try to perform request.
"""
def wrapper(func):
@functools.wraps(func)
def inner(obj, *args, **kwargs):
counter = count
while counter:
counter -= 1
try:
return func(obj, *args, **kwargs)
except requests.exceptions.RequestException as exc:
if not counter:
logging.error('Request for %s failed. Reported '
'reason: %s', args[0], exc.__doc__)
raise
logging.warning('Request for %s failed. Reported '
'reason: %s. Retrying.', args[0],
exc.__doc__)
# Renew the session before retry
obj.authorize()
return inner
return wrapper
class NotAuthorizedError(requests.HTTPError): class NotAuthorizedError(requests.HTTPError):
pass pass
@@ -18,7 +48,7 @@ class Download(object):
"""Download class for taking care of Slack internally uploaded files""" """Download class for taking care of Slack internally uploaded files"""
def __init__(self, args, assets_dir): def __init__(self, args, assets_dir):
self.session = requests.session() self.session = None
self.team = args.team self.team = args.team
self.user = args.user self.user = args.user
self.password = args.password self.password = args.password
@@ -86,15 +116,11 @@ class Download(object):
return path return path
@retry(3)
def _download(self, url, local): def _download(self, url, local):
"""Download file""" """Download file"""
try: res = self.session.get(url, stream=True)
res = self.session.get(url, stream=True)
except requests.exceptions.RequestException as exc:
logging.error('Request for %s failed. Reported reason: %s',
url, exc.__doc__)
raise
with open(local, 'wb') as fobj: with open(local, 'wb') as fobj:
for chunk in res.iter_content(chunk_size=5120): for chunk in res.iter_content(chunk_size=5120):
@@ -106,7 +132,9 @@ class Download(object):
""" """
Authenticate and gather session for Slack Authenticate and gather session for Slack
""" """
self.session = requests.session() # new session
res = self.session.get('https://%s.slack.com/' % self.team) res = self.session.get('https://%s.slack.com/' % self.team)
if not all((self.team, self.password, self.user)): if not all((self.team, self.password, self.user)):
logging.warning('There is neither username, password or team name' logging.warning('There is neither username, password or team name'
' provided. Downloading will not be performed.') ' provided. Downloading will not be performed.')
@@ -114,7 +142,7 @@ class Download(object):
crumb = '' crumb = ''
for line in res.text.split('\n'): for line in res.text.split('\n'):
if 'crumb' in line: if 'crumb' in line and 'value' in line:
crumb = line.split('value=')[1].split('"')[1] crumb = line.split('value=')[1].split('"')[1]
break break
else: else: