From: Hans-Christoph Steiner Date: Wed, 31 May 2017 21:02:28 +0000 (+0200) Subject: regexs for getting packageName and versionCode from filenames X-Git-Tag: 0.8~49^2~3 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=9471bf273117694bf671ae627d0e7dcc956562d3;p=fdroidserver.git regexs for getting packageName and versionCode from filenames This is useful for parsing APK files, which can include packageName, versionCode, and optionally 7 char signing key ID (i.e. ). This also can set the packageName and versionCoe for non APK files, so that it is easy to assign them to metadata files, and to allow for upgrades by setting the versionCode in the filename. --- diff --git a/fdroidserver/common.py b/fdroidserver/common.py index ca02219f..75eac97c 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -55,6 +55,8 @@ from .asynchronousfilereader import AsynchronousFileReader # A signature block file with a .DSA, .RSA, or .EC extension CERT_PATH_REGEX = re.compile(r'^META-INF/.*\.(DSA|EC|RSA)$') +APK_NAME_REGEX = re.compile(r'^([a-zA-Z][\w.]*)_(-?[0-9]+)_?([0-9a-f]{7})?\.apk') +STANDARD_FILE_NAME_REGEX = re.compile(r'^(\w[\w.]*)_(-?[0-9]+)\.\w+') XMLElementTree.register_namespace('android', 'http://schemas.android.com/apk/res/android') diff --git a/fdroidserver/update.py b/fdroidserver/update.py index caea795b..c36fd86e 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -853,14 +853,10 @@ def scan_repo_files(apkcache, repodir, knownapks, use_date_from_file=False): # the static ID is the SHA256 unless it is set in the metadata repo_file['packageName'] = shasum - n = name_utf8.rsplit('_', maxsplit=1) - if len(n) == 2: - packageName = n[0] - versionCode = n[1].split('.')[0] - if re.match('^-?[0-9]+$', versionCode) \ - and common.is_valid_package_name(n[0]): - repo_file['packageName'] = packageName - repo_file['versionCode'] = int(versionCode) + m = common.STANDARD_FILE_NAME_REGEX.match(name_utf8) + if m: + repo_file['packageName'] = m.group(1) + repo_file['versionCode'] = int(m.group(2)) srcfilename = name + b'_src.tar.gz' if os.path.exists(os.path.join(repodir, srcfilename)): repo_file['srcname'] = srcfilename.decode('utf-8') diff --git a/tests/common.TestCase b/tests/common.TestCase index 74364098..f0dcacce 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -281,6 +281,70 @@ class CommonTest(unittest.TestCase): key = "val" """)) + def test_apk_name_regex(self): + good = [ + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_-123456.apk', + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_123456_abcdef0.apk', + 'urzip_-123456.apk', + 'a0_0.apk', + 'Z0_0.apk', + 'a0_0_abcdef0.apk', + 'a_a_a_a_0_abcdef0.apk', + 'a_____0.apk', + 'a_____123456_abcdef0.apk', + 'org.fdroid.fdroid_123456.apk', + # valid, but "_99999" is part of packageName rather than versionCode + 'org.fdroid.fdroid_99999_123456.apk', + # should be valid, but I can't figure out the regex since \w includes digits + # 'πÇÇπÇÇ现代汉语通用字българскиعربي1234ö_0_123bafd.apk', + ] + for name in good: + m = fdroidserver.common.APK_NAME_REGEX.match(name) + self.assertIsNotNone(m) + self.assertIn(m.group(2), ('-123456', '0', '123456')) + self.assertIn(m.group(3), ('abcdef0', None)) + + bad = [ + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_123456_abcdefg.apk', + 'urzip-_-198274.apk', + 'urzip-_0_123bafd.apk', + 'no spaces allowed_123.apk', + '0_0.apk', + '0_0_abcdef0.apk', + ] + for name in bad: + self.assertIsNone(fdroidserver.common.APK_NAME_REGEX.match(name)) + + def test_standard_file_name_regex(self): + good = [ + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_-123456.mp3', + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_123456.mov', + 'Document_-123456.pdf', + 'WTF_0.MOV', + 'Z0_0.ebk', + 'a_a_a_a_0.txt', + 'org.fdroid.fdroid.privileged.ota_123456.zip', + 'πÇÇπÇÇ现代汉语通用字българскиعربي1234ö_0.jpeg', + 'a_____0.PNG', + # valid, but "_99999" is part of packageName rather than versionCode + 'a_____99999_123456.zip', + 'org.fdroid.fdroid_99999_123456.zip', + ] + for name in good: + m = fdroidserver.common.STANDARD_FILE_NAME_REGEX.match(name) + self.assertIsNotNone(m) + self.assertIn(m.group(2), ('-123456', '0', '123456')) + + bad = [ + 'urzipπÇÇπÇÇ现代汉语通用字българскиعربي1234ö_abcdefg.JPEG', + 'urzip-_-198274.zip', + 'urzip-_123bafd.pdf', + 'no spaces allowed_123.foobar', + 'a_____0.', + ] + for name in bad: + self.assertIsNone(fdroidserver.common.STANDARD_FILE_NAME_REGEX.match(name)) + if __name__ == "__main__": parser = optparse.OptionParser() diff --git a/tests/stats/known_apks.txt b/tests/stats/known_apks.txt index ec777242..329213b7 100644 --- a/tests/stats/known_apks.txt +++ b/tests/stats/known_apks.txt @@ -1,4 +1,4 @@ -fake.ota.update_1234.zip 897a92a4ccff4f415f6ba275b2af16d4ecaee60a983b215bddcb9f8964e7a24c 2016-03-10 +fake.ota.update_1234.zip fake.ota.update 2016-03-10 obb.main.oldversion_1444412523.apk obb.main.oldversion 2013-12-31 obb.main.twoversions_1101613.apk obb.main.twoversions 2015-10-12 obb.main.twoversions_1101615.apk obb.main.twoversions 2016-01-01