chiark / gitweb /
update: find alternate PNGs for apps that have an XML app icon
authorHans-Christoph Steiner <hans@eds.org>
Wed, 14 Feb 2018 11:04:39 +0000 (12:04 +0100)
committerHans-Christoph Steiner <hans@eds.org>
Thu, 15 Feb 2018 13:28:45 +0000 (14:28 +0100)
Apps can now use an XML icon, but if the app supports older Android
versions, it'll also contain PNG versions of the same icon.  This finds
those PNGs and uses them instead.

#344
closes #392
fdroiddata#913

fdroidserver/update.py

index 9b97fdb04c59ee5706d89970b9e3beff7c2e29e0..c34885c5b5d022bc6fc7fb0966492d8f4e1c8ca4 100644 (file)
@@ -1442,10 +1442,12 @@ def process_apks(apkcache, repodir, knownapks, use_date_from_apk=False):
 
 
 def extract_apk_icons(icon_filename, apk, apkzip, repo_dir):
-    """
-    Extracts icons from the given APK zip in various densities,
-    saves them into given repo directory
-    and stores their names in the APK metadata dictionary.
+    """Extracts PNG icons from an APK with the supported pixel densities
+
+    Extracts icons from the given APK zip in various densities, saves
+    them into given repo directory and stores their names in the APK
+    metadata dictionary.  If the icon is an XML icon, then this tries
+    to find PNG icon that can replace it.
 
     :param icon_filename: A string representing the icon's file name
     :param apk: A populated dictionary containing APK metadata.
@@ -1453,7 +1455,15 @@ def extract_apk_icons(icon_filename, apk, apkzip, repo_dir):
     :param apkzip: An opened zipfile.ZipFile of the APK file
     :param repo_dir: The directory of the APK's repository
     :return: A list of icon densities that are missing
+
     """
+    res_name_re = re.compile(r'res/(drawable|mipmap)-(x*[hlm]dpi|anydpi).*/(.*)_[0-9]+dp.(png|xml)')
+    pngs = dict()
+    for f in apkzip.namelist():
+        m = res_name_re.match(f)
+        if m and m.group(4) == 'png':
+            density = screen_resolutions[m.group(2)]
+            pngs[m.group(3) + '/' + density] = m.group(0)
     empty_densities = []
     for density in screen_densities:
         if density not in apk['icons_src']:
@@ -1465,12 +1475,11 @@ def extract_apk_icons(icon_filename, apk, apkzip, repo_dir):
 
         # Extract the icon files per density
         if icon_src.endswith('.xml'):
-            png = os.path.basename(icon_src)[:-4] + '.png'
-            for f in apkzip.namelist():
-                if f.endswith(png):
-                    m = re.match(r'res/(drawable|mipmap)-(x*[hlm]dpi).*/', f)
-                    if m and screen_resolutions[m.group(2)] == density:
-                        icon_src = f
+            m = res_name_re.match(icon_src)
+            if m:
+                name = pngs.get(m.group(3) + '/' + str(density))
+                if name:
+                    icon_src = name
             if icon_src.endswith('.xml'):
                 empty_densities.append(density)
                 continue