mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Python's shutil.copy2 fails on Android
Python's shutil.copy2 fails on Android when copying a file's meta data (perm bits, access times) onto certain filesystems. This is documented as python issue28141 https://bugs.python.org/issue28141 These commits workaround that bug by + creating a new function copy_file_metadata in utils.py + wrapping calls to copy2 in a try/except clause that logs any errors that occur but keep execution going + changing the calls to shutil.copy2 to calls to the new function
This commit is contained in:
parent
0942fcb9ec
commit
f8031203d2
2 changed files with 18 additions and 6 deletions
|
|
@ -5,7 +5,6 @@ import calendar
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import shutil
|
|
||||||
from codecs import open
|
from codecs import open
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
@ -21,8 +20,9 @@ from pelican import signals
|
||||||
from pelican.cache import FileStampDataCacher
|
from pelican.cache import FileStampDataCacher
|
||||||
from pelican.contents import Article, Draft, Page, Static, is_valid_content
|
from pelican.contents import Article, Draft, Page, Static, is_valid_content
|
||||||
from pelican.readers import Readers
|
from pelican.readers import Readers
|
||||||
from pelican.utils import (DateFormatter, copy, mkdir_p, posixize_path,
|
from pelican.utils import (DateFormatter, copy, copy_file_metadata, mkdir_p,
|
||||||
process_translations, python_2_unicode_compatible)
|
posixize_path, process_translations,
|
||||||
|
python_2_unicode_compatible)
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
@ -727,8 +727,8 @@ class StaticGenerator(Generator):
|
||||||
source_path = os.path.join(self.path, sc.source_path)
|
source_path = os.path.join(self.path, sc.source_path)
|
||||||
save_as = os.path.join(self.output_path, sc.save_as)
|
save_as = os.path.join(self.output_path, sc.save_as)
|
||||||
mkdir_p(os.path.dirname(save_as))
|
mkdir_p(os.path.dirname(save_as))
|
||||||
shutil.copy2(source_path, save_as)
|
|
||||||
logger.info('Copying %s to %s', sc.source_path, sc.save_as)
|
logger.info('Copying %s to %s', sc.source_path, sc.save_as)
|
||||||
|
copy_file_metadata(source_path, save_as)
|
||||||
|
|
||||||
|
|
||||||
class SourceFileGenerator(Generator):
|
class SourceFileGenerator(Generator):
|
||||||
|
|
|
||||||
|
|
@ -337,7 +337,7 @@ def copy(source, destination, ignores=None):
|
||||||
logger.info('Creating directory %s', dst_dir)
|
logger.info('Creating directory %s', dst_dir)
|
||||||
os.makedirs(dst_dir)
|
os.makedirs(dst_dir)
|
||||||
logger.info('Copying %s to %s', source_, destination_)
|
logger.info('Copying %s to %s', source_, destination_)
|
||||||
shutil.copy2(source_, destination_)
|
copy_file_metadata(source_, destination_)
|
||||||
|
|
||||||
elif os.path.isdir(source_):
|
elif os.path.isdir(source_):
|
||||||
if not os.path.exists(destination_):
|
if not os.path.exists(destination_):
|
||||||
|
|
@ -367,13 +367,25 @@ def copy(source, destination, ignores=None):
|
||||||
dst_path = os.path.join(dst_dir, o)
|
dst_path = os.path.join(dst_dir, o)
|
||||||
if os.path.isfile(src_path):
|
if os.path.isfile(src_path):
|
||||||
logger.info('Copying %s to %s', src_path, dst_path)
|
logger.info('Copying %s to %s', src_path, dst_path)
|
||||||
shutil.copy2(src_path, dst_path)
|
copy_file_metadata(src_path, dst_path)
|
||||||
else:
|
else:
|
||||||
logger.warning('Skipped copy %s (not a file or '
|
logger.warning('Skipped copy %s (not a file or '
|
||||||
'directory) to %s',
|
'directory) to %s',
|
||||||
src_path, dst_path)
|
src_path, dst_path)
|
||||||
|
|
||||||
|
|
||||||
|
def copy_file_metadata(source, destination):
|
||||||
|
'''Copy a file and its metadata (perm bits, access times, ...)'''
|
||||||
|
|
||||||
|
# This function is a workaround for Android python copystat
|
||||||
|
# bug ([issue28141]) https://bugs.python.org/issue28141
|
||||||
|
try:
|
||||||
|
shutil.copy2(source, destination)
|
||||||
|
except OSError as e:
|
||||||
|
logger.warning("A problem occurred copying file %s to %s; %s",
|
||||||
|
source, destination, e)
|
||||||
|
|
||||||
|
|
||||||
def clean_output_dir(path, retention):
|
def clean_output_dir(path, retention):
|
||||||
"""Remove all files from output directory except those in retention list"""
|
"""Remove all files from output directory except those in retention list"""
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue