mirror of
https://github.com/f-droid/fdroidserver.git
synced 2025-11-04 22:40:29 +03:00
update: only copy graphics and screenshots if mtime/size has changed
Instead of copying every time, trust the filesystem to tell us when the file has changed.
This commit is contained in:
parent
fbdecbceb7
commit
508af00e84
3 changed files with 35 additions and 11 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -46,6 +46,7 @@ makebuildserver.config.py
|
||||||
/tests/archive/index.xml
|
/tests/archive/index.xml
|
||||||
/tests/archive/index-v1.jar
|
/tests/archive/index-v1.jar
|
||||||
/tests/archive/index-v1.json
|
/tests/archive/index-v1.json
|
||||||
|
/tests/metadata/org.videolan.vlc/en-US/icon*.png
|
||||||
/tests/repo/index.jar
|
/tests/repo/index.jar
|
||||||
/tests/repo/index_unsigned.jar
|
/tests/repo/index_unsigned.jar
|
||||||
/tests/repo/index-v1.jar
|
/tests/repo/index-v1.jar
|
||||||
|
|
|
||||||
|
|
@ -707,33 +707,52 @@ def _set_author_entry(app, key, f):
|
||||||
app[key] = text
|
app[key] = text
|
||||||
|
|
||||||
|
|
||||||
def _strip_and_copy_image(inpath, outpath):
|
def _strip_and_copy_image(in_file, outpath):
|
||||||
"""Remove any metadata from image and copy it to new path
|
"""Remove any metadata from image and copy it to new path
|
||||||
|
|
||||||
Sadly, image metadata like EXIF can be used to exploit devices.
|
Sadly, image metadata like EXIF can be used to exploit devices.
|
||||||
It is not used at all in the F-Droid ecosystem, so its much safer
|
It is not used at all in the F-Droid ecosystem, so its much safer
|
||||||
just to remove it entirely.
|
just to remove it entirely.
|
||||||
|
|
||||||
"""
|
This uses size+mtime to check for a new file since this process
|
||||||
|
actually modifies the resulting file to strip out the EXIF.
|
||||||
|
|
||||||
|
outpath can be path to either a file or dir. The dir that outpath
|
||||||
|
refers to must exist before calling this.
|
||||||
|
|
||||||
|
"""
|
||||||
|
logging.debug('copying ' + in_file + ' ' + outpath)
|
||||||
|
|
||||||
extension = common.get_extension(inpath)[1]
|
|
||||||
if os.path.isdir(outpath):
|
if os.path.isdir(outpath):
|
||||||
outpath = os.path.join(outpath, os.path.basename(inpath))
|
out_file = os.path.join(outpath, os.path.basename(in_file))
|
||||||
|
else:
|
||||||
|
out_file = outpath
|
||||||
|
|
||||||
|
if os.path.exists(out_file):
|
||||||
|
in_stat = os.stat(in_file)
|
||||||
|
out_stat = os.stat(out_file)
|
||||||
|
if in_stat.st_size == out_stat.st_size \
|
||||||
|
and in_stat.st_mtime == out_stat.st_mtime:
|
||||||
|
return
|
||||||
|
|
||||||
|
extension = common.get_extension(in_file)[1]
|
||||||
if extension == 'png':
|
if extension == 'png':
|
||||||
with open(inpath, 'rb') as fp:
|
with open(in_file, 'rb') as fp:
|
||||||
in_image = Image.open(fp)
|
in_image = Image.open(fp)
|
||||||
in_image.save(outpath, "PNG", optimize=True,
|
in_image.save(out_file, "PNG", optimize=True,
|
||||||
pnginfo=BLANK_PNG_INFO, icc_profile=None)
|
pnginfo=BLANK_PNG_INFO, icc_profile=None)
|
||||||
elif extension == 'jpg' or extension == 'jpeg':
|
elif extension == 'jpg' or extension == 'jpeg':
|
||||||
with open(inpath, 'rb') as fp:
|
with open(in_file, 'rb') as fp:
|
||||||
in_image = Image.open(fp)
|
in_image = Image.open(fp)
|
||||||
data = list(in_image.getdata())
|
data = list(in_image.getdata())
|
||||||
out_image = Image.new(in_image.mode, in_image.size)
|
out_image = Image.new(in_image.mode, in_image.size)
|
||||||
out_image.putdata(data)
|
out_image.putdata(data)
|
||||||
out_image.save(outpath, "JPEG", optimize=True)
|
out_image.save(out_file, "JPEG", optimize=True)
|
||||||
else:
|
else:
|
||||||
raise FDroidException(_('Unsupported file type "{extension}" for repo graphic')
|
raise FDroidException(_('Unsupported file type "{extension}" for repo graphic')
|
||||||
.format(extension=extension))
|
.format(extension=extension))
|
||||||
|
stat_result = os.stat(in_file)
|
||||||
|
os.utime(out_file, times=(stat_result.st_atime, stat_result.st_mtime))
|
||||||
|
|
||||||
|
|
||||||
def copy_triple_t_store_metadata(apps):
|
def copy_triple_t_store_metadata(apps):
|
||||||
|
|
@ -845,7 +864,6 @@ def copy_triple_t_store_metadata(apps):
|
||||||
os.makedirs(destdir, mode=0o755, exist_ok=True)
|
os.makedirs(destdir, mode=0o755, exist_ok=True)
|
||||||
sourcefile = os.path.join(root, f)
|
sourcefile = os.path.join(root, f)
|
||||||
destfile = os.path.join(destdir, repofilename)
|
destfile = os.path.join(destdir, repofilename)
|
||||||
logging.debug('copying ' + sourcefile + ' ' + destfile)
|
|
||||||
_strip_and_copy_image(sourcefile, destfile)
|
_strip_and_copy_image(sourcefile, destfile)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -934,7 +952,6 @@ def insert_localized_app_metadata(apps):
|
||||||
destdir = os.path.join('repo', packageName, locale)
|
destdir = os.path.join('repo', packageName, locale)
|
||||||
if base in GRAPHIC_NAMES and extension in ALLOWED_EXTENSIONS:
|
if base in GRAPHIC_NAMES and extension in ALLOWED_EXTENSIONS:
|
||||||
os.makedirs(destdir, mode=0o755, exist_ok=True)
|
os.makedirs(destdir, mode=0o755, exist_ok=True)
|
||||||
logging.debug('copying ' + os.path.join(root, f) + ' ' + destdir)
|
|
||||||
_strip_and_copy_image(os.path.join(root, f), destdir)
|
_strip_and_copy_image(os.path.join(root, f), destdir)
|
||||||
for d in dirs:
|
for d in dirs:
|
||||||
if d in SCREENSHOT_DIRS:
|
if d in SCREENSHOT_DIRS:
|
||||||
|
|
@ -946,7 +963,6 @@ def insert_localized_app_metadata(apps):
|
||||||
if extension in ALLOWED_EXTENSIONS:
|
if extension in ALLOWED_EXTENSIONS:
|
||||||
screenshotdestdir = os.path.join(destdir, d)
|
screenshotdestdir = os.path.join(destdir, d)
|
||||||
os.makedirs(screenshotdestdir, mode=0o755, exist_ok=True)
|
os.makedirs(screenshotdestdir, mode=0o755, exist_ok=True)
|
||||||
logging.debug('copying ' + f + ' ' + screenshotdestdir)
|
|
||||||
_strip_and_copy_image(f, screenshotdestdir)
|
_strip_and_copy_image(f, screenshotdestdir)
|
||||||
|
|
||||||
repofiles = sorted(glob.glob(os.path.join('repo', '[A-Za-z]*', '[a-z][a-z]*')))
|
repofiles = sorted(glob.glob(os.path.join('repo', '[A-Za-z]*', '[a-z][a-z]*')))
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,13 @@ class UpdateTest(unittest.TestCase):
|
||||||
shutil.copytree(os.path.join('source-files', 'eu.siacs.conversations'),
|
shutil.copytree(os.path.join('source-files', 'eu.siacs.conversations'),
|
||||||
os.path.join('build', 'eu.siacs.conversations'))
|
os.path.join('build', 'eu.siacs.conversations'))
|
||||||
|
|
||||||
|
testfile = os.path.join('repo', 'org.videolan.vlc', 'en-US', 'icon.png')
|
||||||
|
cpdir = os.path.join('metadata', 'org.videolan.vlc', 'en-US')
|
||||||
|
cpfile = os.path.join(cpdir, 'icon.png')
|
||||||
|
os.makedirs(cpdir, exist_ok=True)
|
||||||
|
shutil.copy(testfile, cpfile)
|
||||||
|
shutil.copystat(testfile, cpfile)
|
||||||
|
|
||||||
apps = dict()
|
apps = dict()
|
||||||
for packageName in ('info.guardianproject.urzip', 'org.videolan.vlc', 'obb.mainpatch.current',
|
for packageName in ('info.guardianproject.urzip', 'org.videolan.vlc', 'obb.mainpatch.current',
|
||||||
'com.nextcloud.client', 'com.nextcloud.client.dev',
|
'com.nextcloud.client', 'com.nextcloud.client.dev',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue