12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- import os
- import re
- from glob import glob, escape
- from contextlib import contextmanager
- from subprocess import check_call
- from urllib.parse import urlparse, parse_qs
- from gplaycli.gplaycli import GPlaycli
- class BadPackageNameException(Exception):
- pass
- class dotdict(dict):
- """dot.notation access to dictionary attributes"""
- __getattr__ = dict.get
- __setattr__ = dict.__setitem__
- __delattr__ = dict.__delitem__
- def validate_package_name(package_name):
- # https://developer.android.com/studio/build/application-id
- """
- - It must have at least two segments (one or more dots).
- - Each segment must start with a letter.
- - All characters must be alphanumeric or an underscore [a-zA-Z0-9_].
- """
- reg = r"^(?:[a-zA-Z]+(?:\d*[a-zA-Z_]*)*)(?:\.[a-zA-Z]+(?:\d*[a-zA-Z_]*)*)+$"
- return re.match(reg, package_name) is not None
- class APK:
- def __init__(self, apk, conf={}, conf_file=None):
- self.conf = conf
- self.conf_file = conf_file
- self.package_name = ''
- if 'play.google.com/store/apps/details' in apk:
- url = urlparse(apk)
- if url.netloc == 'play.google.com':
- self.package_name = parse_qs(url.query)['id'][0]
- else:
- self.package_name = apk
- def download(self):
- if not validate_package_name(self.package_name):
- raise BadPackageNameException(f'error downloading {self.package_name}')
- cli = GPlaycli(args=dotdict(self.conf), config_file=self.conf_file)
- cli.download_folder = 'out'
- d = cli.download([self.package_name]) # returns the number of downloaded packages
- if len(d) == 0:
- raise BadPackageNameException(f'error downloading {self.package_name}')
- fname = os.path.join('out', self.package_name + '.apk')
- if os.path.isfile(fname):
- self.file_name = fname
- def check_dimension(self):
- if os.path.getsize(self.file_name) > 50 * 1024 * 1023:
- check_call(['split', '-b', '49M', self.file_name, self.file_name])
- os.remove(self.file_name)
- return glob(escape(self.file_name) + '*')
- @contextmanager
- def send(self):
- files = self.check_dimension() # split if size >= 50MB
- yield files
- for f in files: # removing old files
- os.remove(f)
|