From 40fac10ebcd95095741a243ff621b67335cf9e5b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 14 Feb 2018 13:44:58 +0100 Subject: [PATCH 1/1] update: extract and store XML icons These can then be used by the client. #344 #392 --- fdroidserver/update.py | 72 ++++++++++-------- tests/repo/info.zwanenburg.caffeinetile_4.apk | Bin 0 -> 11740 bytes tests/update.TestCase | 22 +++++- 3 files changed, 60 insertions(+), 34 deletions(-) create mode 100644 tests/repo/info.zwanenburg.caffeinetile_4.apk diff --git a/fdroidserver/update.py b/fdroidserver/update.py index c34885c5..10705a8f 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -61,7 +61,7 @@ APK_PERMISSION_PAT = \ re.compile(".*(name='(?P.*?)')(.*maxSdkVersion='(?P.*?)')?.*") APK_FEATURE_PAT = re.compile(".*name='([^']*)'.*") -screen_densities = ['640', '480', '320', '240', '160', '120'] +screen_densities = ['65534', '640', '480', '320', '240', '160', '120'] screen_resolutions = { "xxxhdpi": '640', "xxhdpi": '480', @@ -96,9 +96,10 @@ def px_to_dpi(px): def get_icon_dir(repodir, density): - if density == '0': + if density == '0' or density == '65534': return os.path.join(repodir, "icons") - return os.path.join(repodir, "icons-%s" % density) + else: + return os.path.join(repodir, "icons-%s" % density) def get_icon_dirs(repodir): @@ -1377,7 +1378,7 @@ def process_apk(apkcache, apkfilename, repodir, knownapks, use_date_from_apk=Fal .format(apkfilename=apkfile) + str(e)) # extract icons from APK zip file - iconfilename = "%s.%s.png" % (apk['packageName'], apk['versionCode']) + iconfilename = "%s.%s" % (apk['packageName'], apk['versionCode']) try: empty_densities = extract_apk_icons(iconfilename, apk, apkzip, repodir) finally: @@ -1464,6 +1465,8 @@ def extract_apk_icons(icon_filename, apk, apkzip, repo_dir): if m and m.group(4) == 'png': density = screen_resolutions[m.group(2)] pngs[m.group(3) + '/' + density] = m.group(0) + + icon_type = None empty_densities = [] for density in screen_densities: if density not in apk['icons_src']: @@ -1471,7 +1474,7 @@ def extract_apk_icons(icon_filename, apk, apkzip, repo_dir): continue icon_src = apk['icons_src'][density] icon_dir = get_icon_dir(repo_dir, density) - icon_dest = os.path.join(icon_dir, icon_filename) + icon_type = '.png' # Extract the icon files per density if icon_src.endswith('.xml'): @@ -1482,59 +1485,68 @@ def extract_apk_icons(icon_filename, apk, apkzip, repo_dir): icon_src = name if icon_src.endswith('.xml'): empty_densities.append(density) - continue + icon_type = '.xml' + icon_dest = os.path.join(icon_dir, icon_filename + icon_type) + try: with open(icon_dest, 'wb') as f: f.write(get_icon_bytes(apkzip, icon_src)) - apk['icons'][density] = icon_filename + apk['icons'][density] = icon_filename + icon_type except (zipfile.BadZipFile, ValueError, KeyError) as e: logging.warning("Error retrieving icon file: %s %s", icon_dest, e) del apk['icons_src'][density] empty_densities.append(density) - if '-1' in apk['icons_src'] and not apk['icons_src']['-1'].endswith('.xml'): + # '-1' here is a remnant of the parsing of aapt output, meaning "no DPI specified" + if '-1' in apk['icons_src']: icon_src = apk['icons_src']['-1'] - icon_path = os.path.join(get_icon_dir(repo_dir, '0'), icon_filename) + icon_type = icon_src[-4:] + icon_path = os.path.join(get_icon_dir(repo_dir, '0'), icon_filename + icon_type) with open(icon_path, 'wb') as f: f.write(get_icon_bytes(apkzip, icon_src)) - im = None - try: - im = Image.open(icon_path) - dpi = px_to_dpi(im.size[0]) - for density in screen_densities: - if density in apk['icons']: - break - if density == screen_densities[-1] or dpi >= int(density): - apk['icons'][density] = icon_filename - shutil.move(icon_path, - os.path.join(get_icon_dir(repo_dir, density), icon_filename)) - empty_densities.remove(density) - break - except Exception as e: - logging.warning(_("Failed reading {path}: {error}") - .format(path=icon_path, error=e)) - finally: - if im and hasattr(im, 'close'): - im.close() + if icon_type == '.png': + im = None + try: + im = Image.open(icon_path) + dpi = px_to_dpi(im.size[0]) + for density in screen_densities: + if density in apk['icons']: + break + if density == screen_densities[-1] or dpi >= int(density): + apk['icons'][density] = icon_filename + shutil.move(icon_path, + os.path.join(get_icon_dir(repo_dir, density), icon_filename)) + empty_densities.remove(density) + break + except Exception as e: + logging.warning(_("Failed reading {path}: {error}") + .format(path=icon_path, error=e)) + finally: + if im and hasattr(im, 'close'): + im.close() if apk['icons']: - apk['icon'] = icon_filename + apk['icon'] = icon_filename + icon_type return empty_densities def fill_missing_icon_densities(empty_densities, icon_filename, apk, repo_dir): """ - Resize existing icons for densities missing in the APK to ensure all densities are available + Resize existing PNG icons for densities missing in the APK to ensure all densities are available :param empty_densities: A list of icon densities that are missing :param icon_filename: A string representing the icon's file name :param apk: A populated dictionary containing APK metadata. Needs to have 'icons' key :param repo_dir: The directory of the APK's repository + """ + icon_filename += '.png' # First try resizing down to not lose quality last_density = None for density in screen_densities: + if density == '65534': # not possible to generate 'anydpi' from other densities + continue if density not in empty_densities: last_density = density continue diff --git a/tests/repo/info.zwanenburg.caffeinetile_4.apk b/tests/repo/info.zwanenburg.caffeinetile_4.apk new file mode 100644 index 0000000000000000000000000000000000000000..bc54a73e946219bf23e003e8ff81de954667dc63 GIT binary patch literal 11740 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 literal 0 HcmV?d00001 diff --git a/tests/update.TestCase b/tests/update.TestCase index 94bf507d..2e9b687b 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -253,14 +253,14 @@ class UpdateTest(unittest.TestCase): apps = fdroidserver.metadata.read_metadata(xref=True) knownapks = fdroidserver.common.KnownApks() apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks, False) - self.assertEqual(len(apks), 12) + self.assertEqual(len(apks), 13) apk = apks[0] self.assertEqual(apk['packageName'], 'com.politedroid') self.assertEqual(apk['versionCode'], 3) self.assertEqual(apk['minSdkVersion'], '3') self.assertEqual(apk['targetSdkVersion'], '3') self.assertFalse('maxSdkVersion' in apk) - apk = apks[5] + apk = apks[6] self.assertEqual(apk['packageName'], 'obb.main.oldversion') self.assertEqual(apk['versionCode'], 1444412523) self.assertEqual(apk['minSdkVersion'], '4') @@ -298,7 +298,6 @@ class UpdateTest(unittest.TestCase): raise Exception('This test must be run in the "tests/" subdir') apk_info = fdroidserver.update.scan_apk('org.dyndns.fules.ck_20.apk') - self.assertEqual(apk_info['icons_src'], {'240': 'res/drawable-hdpi-v4/icon_launcher.png', '120': 'res/drawable-ldpi-v4/icon_launcher.png', '160': 'res/drawable-mdpi-v4/icon_launcher.png', @@ -319,6 +318,21 @@ class UpdateTest(unittest.TestCase): self.assertEqual(apk_info['hashType'], 'sha256') self.assertEqual(apk_info['targetSdkVersion'], '8') + apk_info = fdroidserver.update.scan_apk('org.bitbucket.tickytacky.mirrormirror_4.apk') + self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable-mdpi/mirror.png', + '-1': 'res/drawable-mdpi/mirror.png'}) + + apk_info = fdroidserver.update.scan_apk('repo/info.zwanenburg.caffeinetile_4.apk') + self.assertEqual(apk_info['icons_src'], {'160': 'res/drawable/ic_coffee_on.xml', + '-1': 'res/drawable/ic_coffee_on.xml'}) + + apk_info = fdroidserver.update.scan_apk('repo/com.politedroid_6.apk') + self.assertEqual(apk_info['icons_src'], {'120': 'res/drawable-ldpi-v4/icon.png', + '160': 'res/drawable-mdpi-v4/icon.png', + '240': 'res/drawable-hdpi-v4/icon.png', + '320': 'res/drawable-xhdpi-v4/icon.png', + '-1': 'res/drawable-mdpi-v4/icon.png'}) + def test_scan_apk_no_sig(self): config = dict() fdroidserver.common.fill_config_defaults(config) @@ -527,7 +541,7 @@ class UpdateTest(unittest.TestCase): knownapks = fdroidserver.common.KnownApks() apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks, False) fdroidserver.update.translate_per_build_anti_features(apps, apks) - self.assertEqual(len(apks), 12) + self.assertEqual(len(apks), 13) foundtest = False for apk in apks: if apk['packageName'] == 'com.politedroid' and apk['versionCode'] == 3: -- 2.30.2