mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
Tested on ci. See https://github.com/PyCQA/flake8-import-order . In the process did some other cleanups and https://en.wikipedia.org/wiki/Code_refactoring .
243 lines
7.8 KiB
Python
Executable file
243 lines
7.8 KiB
Python
Executable file
#! /usr/bin/env python3
|
|
# -*- coding: iso-8859-1 -*-
|
|
|
|
import glob
|
|
import hashlib
|
|
import logging
|
|
import os
|
|
import sys
|
|
from zipfile import ZipFile, ZipInfo
|
|
|
|
from clint.textui import progress
|
|
|
|
import requests
|
|
|
|
|
|
cachefiles = [
|
|
('https://dl.google.com/android/repository/platform-tools-latest-linux.zip',
|
|
'',
|
|
'platform-tools'),
|
|
('https://dl.google.com/android/repository/tools_r25.2.5-linux.zip',
|
|
'577516819c8b5fae680f049d39014ff1ba4af870b687cab10595783e6f22d33e',
|
|
'tools'),
|
|
('https://dl.google.com/android/repository/android-19_r04.zip',
|
|
'5efc3a3a682c1d49128daddb6716c433edf16e63349f32959b6207524ac04039',
|
|
'platform'),
|
|
('https://dl.google.com/android/repository/build-tools_r26-linux.zip',
|
|
'7422682f92fb471d4aad4c053c9982a9a623377f9d5e4de7a73cd44ebf2f3c61',
|
|
'build-tools'),
|
|
('https://dl.google.com/'
|
|
'android/repository/android-ndk-r12b-linux-x86_64.zip',
|
|
'eafae2d614e5475a3bcfd7c5f201db5b963cc1290ee3e8ae791ff0c66757781e',
|
|
'ndk'),
|
|
]
|
|
|
|
# https://stackoverflow.com/questions/39296101:
|
|
|
|
|
|
class MyZipFile(ZipFile):
|
|
|
|
def extract(self, member, path=None, pwd=None):
|
|
if not isinstance(member, ZipInfo):
|
|
member = self.getinfo(member)
|
|
|
|
if path is None:
|
|
path = os.getcwd()
|
|
|
|
ret_val = self._extract_member(member, path, pwd)
|
|
attr = member.external_attr >> 16
|
|
os.chmod(ret_val, attr)
|
|
return ret_val
|
|
|
|
# Reused from fdroidserver:
|
|
|
|
|
|
def sha256_for_file(path):
|
|
with open(path, 'rb') as f:
|
|
s = hashlib.sha256()
|
|
while True:
|
|
data = f.read(4096)
|
|
if not data:
|
|
break
|
|
s.update(data)
|
|
return s.hexdigest()
|
|
|
|
# Adapted from fdroidserver:
|
|
|
|
|
|
def update_cache(cachedir, cachefiles):
|
|
for srcurl, shasum, typ in cachefiles:
|
|
filename = os.path.basename(srcurl)
|
|
local_filename = os.path.join(cachedir, filename)
|
|
|
|
if os.path.exists(local_filename):
|
|
local_length = os.path.getsize(local_filename)
|
|
else:
|
|
|
|
local_length = -1
|
|
|
|
if (typ == 'ndk') and (ndkloc is not None):
|
|
continue
|
|
elif (typ != 'tools') and (sdkloc is not None):
|
|
continue
|
|
|
|
resume_header = {}
|
|
download = True
|
|
|
|
try:
|
|
r = requests.head(srcurl, allow_redirects=True, timeout=60)
|
|
if r.status_code == 200:
|
|
content_length = int(r.headers.get('content-length'))
|
|
else:
|
|
content_length = local_length # skip the download
|
|
except requests.exceptions.RequestException as e:
|
|
content_length = local_length # skip the download
|
|
logger.warn('%s', e)
|
|
|
|
if local_length == content_length:
|
|
download = False
|
|
elif local_length > content_length:
|
|
logger.info('deleting corrupt file from cache: %s',
|
|
local_filename)
|
|
os.remove(local_filename)
|
|
logger.info("Downloading %s to cache", filename)
|
|
elif local_length > -1 and local_length < content_length:
|
|
logger.info("Resuming download of %s", local_filename)
|
|
resume_header = {
|
|
'Range': 'bytes=%d-%d' % (local_length, content_length)}
|
|
else:
|
|
logger.info("Downloading %s to cache", filename)
|
|
|
|
if download:
|
|
r = requests.get(srcurl, headers=resume_header,
|
|
stream=True, verify=False, allow_redirects=True)
|
|
content_length = int(r.headers.get('content-length'))
|
|
with open(local_filename, 'ab') as f:
|
|
for chunk in progress.bar(
|
|
r.iter_content(chunk_size=65536),
|
|
expected_size=(content_length / 65536) + 1):
|
|
if chunk: # filter out keep-alive new chunks
|
|
f.write(chunk)
|
|
if not shasum == '':
|
|
v = sha256_for_file(local_filename)
|
|
if v == shasum:
|
|
logger.info("Shasum verified for %s", local_filename)
|
|
else:
|
|
logger.critical(
|
|
"Invalid shasum of '%s' detected for %s", v, local_filename)
|
|
os.remove(local_filename)
|
|
sys.exit(1)
|
|
|
|
# Build the sdk from zips.
|
|
|
|
|
|
def build_sdk(sdkdir, cachedir, cachfiles):
|
|
for srcurl, shasum, typ in cachefiles:
|
|
filename = os.path.basename(srcurl)
|
|
local_filename = os.path.join(cachedir, filename)
|
|
|
|
if typ == 'tools':
|
|
if os.path.exists(local_filename):
|
|
print('Extract: %s' % local_filename)
|
|
zf = MyZipFile(local_filename)
|
|
zf.extractall(sdkdir)
|
|
elif typ == 'platform-tools':
|
|
if (sdkloc is None) and (os.path.exists(local_filename)):
|
|
print('Extract: %s' % local_filename)
|
|
zf = MyZipFile(local_filename)
|
|
zf.extractall(sdkdir)
|
|
else:
|
|
print('Link to: %s' % sdkloc)
|
|
os.symlink(sdkloc + '/platform-tools',
|
|
sdkdir + '/platform-tools')
|
|
elif typ == 'platform':
|
|
if (sdkloc is None) and (os.path.exists(local_filename)):
|
|
print('Extract: %s' % local_filename)
|
|
zf = MyZipFile(local_filename)
|
|
zf.extractall(sdkdir + '/platforms')
|
|
else:
|
|
print('Link to: %s' % sdkloc)
|
|
os.symlink(sdkloc + '/platforms', sdkdir + '/platforms')
|
|
elif typ == 'build-tools':
|
|
if (sdkloc is None) and (os.path.exists(local_filename)):
|
|
print('Extract: %s' % local_filename)
|
|
zf = MyZipFile(local_filename)
|
|
zf.extractall(sdkdir + '/build-tools')
|
|
else:
|
|
print('Link to: %s' % sdkloc)
|
|
os.symlink(sdkloc + '/build-tools', sdkdir + '/build-tools')
|
|
elif typ == 'ndk':
|
|
if ndkloc is None:
|
|
print('Extract: %s' % local_filename)
|
|
zf = MyZipFile(local_filename)
|
|
zf.extractall(sdkdir)
|
|
lst = glob.glob(sdkdir + '/*-ndk-*')
|
|
print(lst)
|
|
os.rename(lst[0], sdkdir + '/ndk-bundle')
|
|
else:
|
|
print('Link to: %s' % ndkloc)
|
|
os.symlink(ndkloc, sdkdir + '/ndk-bundle')
|
|
|
|
|
|
logger = logging.getLogger('prepare-fdroid-build')
|
|
logging.basicConfig(format='%(message)s', level=logging.INFO)
|
|
logger.setLevel(logging.INFO)
|
|
|
|
# command line arguments
|
|
|
|
sdkloc = None
|
|
ndkloc = None
|
|
if len(sys.argv) > 1:
|
|
sdkloc = sys.argv[1]
|
|
if (len(sdkloc) > 0) and (sdkloc[-1] == '/'):
|
|
sdkloc = sdkloc[:-1]
|
|
if not os.path.isdir(sdkloc):
|
|
sdkloc = None
|
|
|
|
if len(sys.argv) > 2:
|
|
ndkloc = sys.argv[2]
|
|
if (len(ndkloc) > 0) and (ndkloc[-1] == '/'):
|
|
ndkloc = ndkloc[:-1]
|
|
if not os.path.isdir(ndkloc):
|
|
ndkloc = None
|
|
|
|
fdroidmode = None
|
|
if len(sys.argv) > 3:
|
|
fdroidmode = sys.argv[3]
|
|
if (len(fdroidmode) > 0):
|
|
fdroidmode = '1'
|
|
|
|
if sdkloc == "":
|
|
sdkloc = None
|
|
if ndkloc == "":
|
|
ndkloc = None
|
|
|
|
logger.info('sdkloc = %s' % sdkloc)
|
|
logger.info('ndkloc = %s' % ndkloc)
|
|
|
|
# sdkloc and ndkloc already set by the user and fdroidmode:
|
|
# nothing to do.
|
|
|
|
if (sdkloc is not None) and (ndkloc is not None) and (fdroidmode is not None):
|
|
sys.exit(0)
|
|
|
|
# cache dir (using the same as in fdroidserver/buildserver)
|
|
cachedir = os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver')
|
|
logger.info('cachedir name is: %s', cachedir)
|
|
|
|
if not os.path.exists(cachedir):
|
|
os.makedirs(cachedir, 0o755)
|
|
logger.info('created cachedir %s', cachedir)
|
|
|
|
# sdkdir location
|
|
sdkdir = os.path.join(os.getenv('HOME'), '.cache', 'sdk-for-p4a')
|
|
logger.info('sdkdir name is: %s', sdkdir)
|
|
|
|
if not os.path.exists(sdkdir):
|
|
os.makedirs(sdkdir, 0o755)
|
|
logger.debug('created sdkdir %s', sdkdir)
|
|
|
|
update_cache(cachedir, cachefiles)
|
|
build_sdk(sdkdir, cachedir, cachefiles)
|
|
else:
|
|
logger.info('sdkdir %s already exists', sdkdir)
|