Compare commits

..

14 Commits

Author SHA1 Message Date
Jose Diaz-Gonzalez
63441ebfbc Release version 0.41.0 2022-03-02 02:36:41 -05:00
Jose Diaz-Gonzalez
7ad324225e Merge pull request #191 from SkySoft-ATM/bug/lfs_mirror
git lfs clone does not respect --mirror
2022-03-02 02:34:17 -05:00
Louis Parisot
885e94a102 git lfs clone doe snot respect --mirror 2022-02-03 11:45:59 +01:00
Jose Diaz-Gonzalez
9e1800f56e Release version 0.40.2 2021-12-29 12:49:10 -05:00
Jose Diaz-Gonzalez
d057ee0d04 Merge pull request #186 from atinary-afoulon/patch-1
Fix lint issues raised by Flake8
2021-12-29 12:48:30 -05:00
atinary-afoulon
64562f2460 Fix lint issues raised by Flake8
According to job: 
[ https://app.circleci.com/pipelines/github/josegonzalez/python-github-backup/30/workflows/74eb93f2-2505-435d-b728-03b3cc04c14a/jobs/23 ]

Failed on the following checks:
./github_backup/github_backup.py:20:1: F811 redefinition of unused 'logging' from line 14
./github_backup/github_backup.py:45:1: E302 expected 2 blank lines, found 1
./github_backup/github_backup.py:136:20: E251 unexpected spaces around keyword / parameter equals
2021-12-13 14:33:21 +01:00
Jose Diaz-Gonzalez
f7f9ffd017 Release version 0.40.1 2021-09-22 12:29:08 -04:00
Jose Diaz-Gonzalez
048ef04e2a Merge pull request #180 from whwright/revert-to-fetch
Revert to fetch
2021-09-22 11:06:18 -04:00
Harrison Wright
b1acfed83a Revert to fetch 2021-07-14 10:53:14 -05:00
Jose Diaz-Gonzalez
18e78a4d66 Release version 0.40.0 2021-07-12 00:44:33 -04:00
Jose Diaz-Gonzalez
1ed5427043 Merge pull request #177 from jacekn/retry
Add retry on certain network errors
2021-07-12 00:43:19 -04:00
Jose Diaz-Gonzalez
c2e3665ed8 Merge pull request #178 from pew/patch-1
pull changes from remote
2021-07-12 00:43:10 -04:00
Jonas
0a30a92fe4 pull changes from remote
use `git pull` to pull actual files from the remote instead of using `fetch` for only the metadata
2021-07-06 06:21:06 +02:00
Jacek Nykis
cc52587f52 Add retry on certain network errors
This change includes certain network level errors in the retry logic.
It partially address #110 but I think more comprehensive fix would be useful.
2021-07-01 14:39:10 +01:00
2 changed files with 43 additions and 10 deletions

View File

@@ -1 +1 @@
__version__ = '0.39.0' __version__ = '0.41.0'

View File

@@ -11,7 +11,6 @@ import datetime
import errno import errno
import getpass import getpass
import json import json
import logging
import os import os
import re import re
import select import select
@@ -28,6 +27,7 @@ from urllib.request import urlopen
from urllib.request import Request from urllib.request import Request
from urllib.request import HTTPRedirectHandler from urllib.request import HTTPRedirectHandler
from urllib.request import build_opener from urllib.request import build_opener
from http.client import IncompleteRead
try: try:
from . import __version__ from . import __version__
@@ -41,6 +41,7 @@ FNULL = open(os.devnull, 'w')
def _get_log_date(): def _get_log_date():
return datetime.datetime.isoformat(datetime.datetime.now()) return datetime.datetime.isoformat(datetime.datetime.now())
def log_info(message): def log_info(message):
""" """
Log message (str) or messages (List[str]) to stdout Log message (str) or messages (List[str]) to stdout
@@ -132,7 +133,7 @@ def mask_password(url, secret='*****'):
return url.replace(parsed.password, secret) return url.replace(parsed.password, secret)
def parse_args(args = None): def parse_args(args=None):
parser = argparse.ArgumentParser(description='Backup a github account') parser = argparse.ArgumentParser(description='Backup a github account')
parser.add_argument('user', parser.add_argument('user',
metavar='USER', metavar='USER',
@@ -436,6 +437,21 @@ def retrieve_data_gen(args, template, query_args=None, single_request=False):
r, errors = _get_response(request, auth, template) r, errors = _get_response(request, auth, template)
status_code = int(r.getcode()) status_code = int(r.getcode())
# Check if we got correct data
try:
response = json.loads(r.read().decode('utf-8'))
except IncompleteRead:
log_warning("Incomplete read error detected")
read_error = True
except json.decoder.JSONDecodeError:
log_warning("JSON decode error detected")
read_error = True
except TimeoutError:
log_warning("Tiemout error detected")
read_error = True
else:
read_error = False
# be gentle with API request limit and throttle requests if remaining requests getting low # be gentle with API request limit and throttle requests if remaining requests getting low
limit_remaining = int(r.headers.get('x-ratelimit-remaining', 0)) limit_remaining = int(r.headers.get('x-ratelimit-remaining', 0))
if args.throttle_limit and limit_remaining <= args.throttle_limit: if args.throttle_limit and limit_remaining <= args.throttle_limit:
@@ -446,21 +462,37 @@ def retrieve_data_gen(args, template, query_args=None, single_request=False):
time.sleep(args.throttle_pause) time.sleep(args.throttle_pause)
retries = 0 retries = 0
while retries < 3 and status_code == 502: while retries < 3 and (status_code == 502 or read_error):
log_warning('API request returned HTTP 502: Bad Gateway. Retrying in 5 seconds') log_warning('API request failed. Retrying in 5 seconds')
retries += 1 retries += 1
time.sleep(5) time.sleep(5)
request = _construct_request(per_page, page, query_args, template, auth, as_app=args.as_app) # noqa request = _construct_request(per_page, page, query_args, template, auth, as_app=args.as_app) # noqa
r, errors = _get_response(request, auth, template) r, errors = _get_response(request, auth, template)
status_code = int(r.getcode()) status_code = int(r.getcode())
try:
response = json.loads(r.read().decode('utf-8'))
read_error = False
except IncompleteRead:
log_warning("Incomplete read error detected")
read_error = True
except json.decoder.JSONDecodeError:
log_warning("JSON decode error detected")
read_error = True
except TimeoutError:
log_warning("Tiemout error detected")
read_error = True
if status_code != 200: if status_code != 200:
template = 'API request returned HTTP {0}: {1}' template = 'API request returned HTTP {0}: {1}'
errors.append(template.format(status_code, r.reason)) errors.append(template.format(status_code, r.reason))
raise Exception(', '.join(errors)) raise Exception(', '.join(errors))
response = json.loads(r.read().decode('utf-8')) if read_error:
template = 'API request problem reading response for {0}'
errors.append(template.format(request))
raise Exception(', '.join(errors))
if len(errors) == 0: if len(errors) == 0:
if type(response) == list: if type(response) == list:
for resp in response: for resp in response:
@@ -1074,16 +1106,17 @@ def fetch_repository(name,
masked_remote_url, masked_remote_url,
local_dir)) local_dir))
if bare_clone: if bare_clone:
git_command = ['git', 'clone', '--mirror', remote_url, local_dir]
logging_subprocess(git_command, None)
if lfs_clone: if lfs_clone:
git_command = ['git', 'lfs', 'clone', '--mirror', remote_url, local_dir] git_command = ['git', 'lfs', 'fetch', '--all', '--prune']
else: logging_subprocess(git_command, None, cwd=local_dir)
git_command = ['git', 'clone', '--mirror', remote_url, local_dir]
else: else:
if lfs_clone: if lfs_clone:
git_command = ['git', 'lfs', 'clone', remote_url, local_dir] git_command = ['git', 'lfs', 'clone', remote_url, local_dir]
else: else:
git_command = ['git', 'clone', remote_url, local_dir] git_command = ['git', 'clone', remote_url, local_dir]
logging_subprocess(git_command, None) logging_subprocess(git_command, None)
def backup_account(args, output_directory): def backup_account(args, output_directory):