import zipfile
import hashlib
import pickle
+import urlparse
from datetime import datetime, timedelta
from xml.dom.minidom import Document
from argparse import ArgumentParser
if validapks == 0 and not app.Disabled:
wikidata += '\n[[Category:Apps with no packages]]\n'
if cantupdate and not app.Disabled:
- wikidata += "\n[[Category:Apps we can't update]]\n"
+ wikidata += "\n[[Category:Apps we cannot update]]\n"
if buildfails and not app.Disabled:
wikidata += "\n[[Category:Apps with failing builds]]\n"
elif not gotcurrentver and not cantupdate and not app.Disabled and app.UpdateCheckMode != "Static":
return md5(cert_encoded.encode('hex')).hexdigest()
-def scan_apks(apps, apkcache, repodir, knownapks):
+def scan_apks(apps, apkcache, repodir, knownapks, use_date_from_apk=False):
"""Scan the apks in the given repo directory.
This also extracts the icons.
:param apkcache: current apk cache information
:param repodir: repo directory to scan
:param knownapks: known apks info
+ :param use_date_from_apk: use date from APK (instead of current date)
+ for newly added APKs
:returns: (apks, cachechanged) where apks is a list of apk information,
and cachechanged is True if the apkcache got changed.
"""
# has to be more than 24 hours newer because ZIP/APK files do not
# store timezone info
manifest = apkzip.getinfo('AndroidManifest.xml')
- dt_obj = datetime(*manifest.date_time)
- checkdt = dt_obj - timedelta(1)
- if datetime.today() < checkdt:
- logging.warn('System clock is older than manifest in: '
- + apkfilename + '\nSet clock to that time using:\n'
- + 'sudo date -s "' + str(dt_obj) + '"')
+ if manifest.date_time[1] == 0: # month can't be zero
+ logging.debug('AndroidManifest.xml has no date')
+ else:
+ dt_obj = datetime(*manifest.date_time)
+ checkdt = dt_obj - timedelta(1)
+ if datetime.today() < checkdt:
+ logging.warn('System clock is older than manifest in: '
+ + apkfilename
+ + '\nSet clock to that time using:\n'
+ + 'sudo date -s "' + str(dt_obj) + '"')
iconfilename = "%s.%s.png" % (
apk['id'],
# Record in known apks, getting the added date at the same time..
added = knownapks.recordapk(apk['apkname'], apk['id'])
if added:
+ if use_date_from_apk and manifest.date_time[1] != 0:
+ added = datetime(*manifest.date_time).timetuple()
+ logging.debug("Using date from APK")
+
apk['added'] = added
apkcache[apkfilename] = apk
repoel = doc.createElement("repo")
+ mirrorcheckfailed = False
+ for mirror in config.get('mirrors', []):
+ base = os.path.basename(urlparse.urlparse(mirror).path.rstrip('/'))
+ if config.get('nonstandardwebroot') is not True and base != 'fdroid':
+ logging.error("mirror '" + mirror + "' does not end with 'fdroid'!")
+ mirrorcheckfailed = True
+ if mirrorcheckfailed:
+ sys.exit(1)
+
if archive:
repoel.setAttribute("name", config['archive_name'])
if config['repo_maxage'] != 0:
repoel.setAttribute("icon", os.path.basename(config['archive_icon']))
repoel.setAttribute("url", config['archive_url'])
addElement('description', config['archive_description'], doc, repoel)
+ urlbasepath = os.path.basename(urlparse.urlparse(config['archive_url']).path)
+ for mirror in config.get('mirrors', []):
+ addElement('mirror', urlparse.urljoin(mirror, urlbasepath), doc, repoel)
else:
repoel.setAttribute("name", config['repo_name'])
repoel.setAttribute("icon", os.path.basename(config['repo_icon']))
repoel.setAttribute("url", config['repo_url'])
addElement('description', config['repo_description'], doc, repoel)
+ urlbasepath = os.path.basename(urlparse.urlparse(config['repo_url']).path)
+ for mirror in config.get('mirrors', []):
+ addElement('mirror', urlparse.urljoin(mirror, urlbasepath), doc, repoel)
- repoel.setAttribute("version", "14")
+ repoel.setAttribute("version", "15")
repoel.setAttribute("timestamp", str(int(time.time())))
nosigningkey = False
help="Clean update - don't uses caches, reprocess all apks")
parser.add_argument("--nosign", action="store_true", default=False,
help="When configured for signed indexes, create only unsigned indexes at this stage")
+ parser.add_argument("--use-date-from-apk", action="store_true", default=False,
+ help="Use date from apk instead of current time for newly added apks")
options = parser.parse_args()
config = common.read_config(options)
delete_disabled_builds(apps, apkcache, repodirs)
# Scan all apks in the main repo
- apks, cachechanged = scan_apks(apps, apkcache, repodirs[0], knownapks)
+ apks, cachechanged = scan_apks(apps, apkcache, repodirs[0], knownapks, options.use_date_from_apk)
# Generate warnings for apk's with no metadata (or create skeleton
# metadata files, if requested on the command line)
# Scan the archive repo for apks as well
if len(repodirs) > 1:
- archapks, cc = scan_apks(apps, apkcache, repodirs[1], knownapks)
+ archapks, cc = scan_apks(apps, apkcache, repodirs[1], knownapks, options.use_date_from_apk)
if cc:
cachechanged = True
else:
if app.Name is None:
app.Name = bestapk['name']
app.icon = bestapk['icon'] if 'icon' in bestapk else None
+ if app.CurrentVersionCode is None:
+ app.CurrentVersionCode = str(bestver)
# Sort the app list by name, then the web site doesn't have to by default.
# (we had to wait until we'd scanned the apks to do this, because mostly the