Skip to content

Commit

Permalink
Requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
rehmatworks committed Feb 19, 2021
1 parent a0fbac1 commit c6f9313
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 96 deletions.
Binary file added .DS_Store
Binary file not shown.
Binary file added gplaydl/.DS_Store
Binary file not shown.
176 changes: 88 additions & 88 deletions gplaydl/gplaydl.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,185 +10,185 @@
from termcolor import colored
from getpass import getpass

devicecode = "shamu"
devicecode = 'shamu'

ap = argparse.ArgumentParser(
description="Command line APK downloader for Google Play Store.")
subparsers = ap.add_subparsers(dest="action")
description='Command line APK downloader for Google Play Store.')
subparsers = ap.add_subparsers(dest='action')

# Args for configuring Google auth
cp = subparsers.add_parser("configure", help="Configure Google login info.")
cp.add_argument("--device", dest="device",
help="Device code name", default=devicecode)
cp = subparsers.add_parser('configure', help='Configure Google login info.')
cp.add_argument('--device', dest='device',
help='Device code name', default=devicecode)

# Args for downloading an app
dl = subparsers.add_parser(
"download", help="Download an app or a game from Google Play.")
dl.add_argument("--device", dest="device",
help="Device code name", default=devicecode)
dl.add_argument("--packageId", required=True, dest="packageId",
help="Package ID of the app, i.e. com.whatsapp")
dl.add_argument("--path", dest="storagepath",
help="Path where to store downloaded files", default=False)
dl.add_argument("--ex", dest="expansionfiles",
help="Download expansion (OBB) data if available", default='y')
dl.add_argument("--splits", dest="splits",
help="Download split APKs if available", default='y')
'download', help='Download an app or a game from Google Play.')
dl.add_argument('--device', dest='device',
help='Device code name', default=devicecode)
dl.add_argument('--packageId', required=True, dest='packageId',
help='Package ID of the app, i.e. com.whatsapp')
dl.add_argument('--path', dest='storagepath',
help='Path where to store downloaded files', default=False)
dl.add_argument('--ex', dest='expansionfiles',
help='Download expansion (OBB) data if available', default='y')
dl.add_argument('--splits', dest='splits',
help='Download split APKs if available', default='y')

args = ap.parse_args()

if (args.action == 'download' or args.action == 'configure') and args.device:
devicecode = args.device

HOMEDIR = expanduser("~/.gplaydl")
CACHEDIR = os.path.join(HOMEDIR, "cache")
CACHEFILE = os.path.join(CACHEDIR, "%s.txt" % devicecode)
CONFIGDIR = os.path.join(HOMEDIR, "config")
CONFIGFILE = os.path.join(CONFIGDIR, "config.txt")
HOMEDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), '.gplaydl')
CACHEDIR = os.path.join(HOMEDIR, 'cache')
CACHEFILE = os.path.join(CACHEDIR, '%s.txt' % devicecode)
CONFIGDIR = os.path.join(HOMEDIR, 'config')
CONFIGFILE = os.path.join(CONFIGDIR, 'config.txt')


def sizeof_fmt(num):
for unit in ["", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"]:
for unit in ['', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB']:
if abs(num) < 1024.0:
return "%3.1f%s" % (num, unit)
return '%3.1f%s' % (num, unit)
num /= 1024.0
return "%.1f%s" % (num, "Yi")
return '%.1f%s' % (num, 'Yi')


def configureauth():
email = None
password = None
while email is None:
em = input("Google Email: ").strip()
em = input('Google Email: ').strip()
if validators.email(em):
email = em
else:
print(colored("Provided email is invalid.", "red"))
print(colored('Provided email is invalid.', 'red'))

while password is None:
password = getpass("Google Password: ").strip()
password = getpass('Google Password: ').strip()
if len(password) == 0:
password = None

if not os.path.exists(CONFIGDIR):
os.makedirs(CONFIGDIR, exist_ok=True)

server = GooglePlayAPI("en_US", "America/New York", devicecode)
server = GooglePlayAPI('en_US', 'America/New York', devicecode)
try:
server.login(email, password)
server.details("com.whatsapp")
config = {"email": email, "password": password}
pickle.dump(config, open(CONFIGFILE, "wb"))
server.details('com.whatsapp')
config = {'email': email, 'password': password}
pickle.dump(config, open(CONFIGFILE, 'wb'))
print(colored(
"Configuration file created successfully! Try downloading an app now.", "green"))
'Configuration file created successfully! Try downloading an app now.', 'green'))
except Exception as e:
print(colored(str(e), "yellow"))
print(colored(str(e), 'yellow'))
configureauth()


def downloadapp(packageId):
if args.storagepath:
storagepath = args.storagepath
else:
storagepath = "./"
storagepath = './'
if os.path.exists(CONFIGFILE):
with open(CONFIGFILE, "rb") as f:
with open(CONFIGFILE, 'rb') as f:
config = pickle.load(f)
email = config.get("email")
password = config.get("password")
email = config.get('email')
password = config.get('password')
else:
print(
colored("Login credentials not found. Please configure them first.", "yellow"))
colored('Login credentials not found. Please configure them first.', 'yellow'))
configureauth()
sys.exit(0)

server = GooglePlayAPI("en_US", "America/New York", args.device)
server = GooglePlayAPI('en_US', 'America/New York', args.device)
try:
server = do_login(server, email, password)
except Exception as e:
print(colored("Login failed. Please re-configure your auth.", "yellow"))
print(colored('Login failed. Please re-configure your auth.', 'yellow'))
configureauth()

try:
print(colored("Attempting to download %s" % packageId, "blue"))
print(colored('Attempting to download %s' % packageId, 'blue'))
expansionFiles = True if args.expansionfiles == 'y' else False
download = server.download(packageId, expansion_files=expansionFiles)
apkfname = "%s.apk" % download.get("docId")
apkfname = '%s.apk' % download.get('docId')
apkpath = os.path.join(storagepath, apkfname)

if not os.path.isdir(storagepath):
os.makedirs(storagepath, exist_ok=True)
saved = 0
totalsize = int(download.get("file").get("total_size"))
print(colored("Downloading %s....." % apkfname, "blue"))
with open(apkpath, "wb") as apkf:
for chunk in download.get("file").get("data"):
totalsize = int(download.get('file').get('total_size'))
print(colored('Downloading %s.....' % apkfname, 'blue'))
with open(apkpath, 'wb') as apkf:
for chunk in download.get('file').get('data'):
saved += len(chunk)
apkf.write(chunk)
done = int(50 * saved / totalsize)
sys.stdout.write("\r[%s%s] %s%s (%s/%s)" % ("*" * done, " " * (50-done), int(
(saved/totalsize)*100), "%", sizeof_fmt(saved), sizeof_fmt(totalsize)))
print("")
print(colored("APK downloaded and stored at %s" % apkpath, "green"))
sys.stdout.write('\r[%s%s] %s%s (%s/%s)' % ('*' * done, ' ' * (50-done), int(
(saved/totalsize)*100), '%', sizeof_fmt(saved), sizeof_fmt(totalsize)))
print('')
print(colored('APK downloaded and stored at %s' % apkpath, 'green'))

if args.splits == 'y':
for split in download.get("splits"):
name = "%s.apk" % (split.get("name"))
print(colored("Downloading %s....." % name, "blue"))
for split in download.get('splits'):
name = '%s.apk' % (split.get('name'))
print(colored('Downloading %s.....' % name, 'blue'))
splitpath = os.path.join(
storagepath, download.get("docId"), name)
if not os.path.isdir(os.path.join(storagepath, download.get("docId"))):
storagepath, download.get('docId'), name)
if not os.path.isdir(os.path.join(storagepath, download.get('docId'))):
os.makedirs(os.path.join(
storagepath, download.get("docId")), exist_ok=True)
storagepath, download.get('docId')), exist_ok=True)

saved = 0
totalsize = int(split.get("file").get("total_size"))
with open(splitpath, "wb") as splitf:
for chunk in split.get("file").get("data"):
totalsize = int(split.get('file').get('total_size'))
with open(splitpath, 'wb') as splitf:
for chunk in split.get('file').get('data'):
splitf.write(chunk)
saved += len(chunk)
done = int(50 * saved / totalsize)
sys.stdout.write("\r[%s%s] %s%s (%s/%s)" % ("*" * done, " " * (50-done), int(
(saved/totalsize)*100), "%", sizeof_fmt(saved), sizeof_fmt(totalsize)))
print("")
print(colored("Split APK downloaded and stored at %s" %
splitpath, "green"))

for obb in download.get("additionalData"):
name = "%s.%s.%s.obb" % (obb.get("type"), str(
obb.get("versionCode")), download.get("docId"))
print(colored("Downloading %s....." % name, "blue"))
obbpath = os.path.join(storagepath, download.get("docId"), name)
if not os.path.isdir(os.path.join(storagepath, download.get("docId"))):
sys.stdout.write('\r[%s%s] %s%s (%s/%s)' % ('*' * done, ' ' * (50-done), int(
(saved/totalsize)*100), '%', sizeof_fmt(saved), sizeof_fmt(totalsize)))
print('')
print(colored('Split APK downloaded and stored at %s' %
splitpath, 'green'))

for obb in download.get('additionalData'):
name = '%s.%s.%s.obb' % (obb.get('type'), str(
obb.get('versionCode')), download.get('docId'))
print(colored('Downloading %s.....' % name, 'blue'))
obbpath = os.path.join(storagepath, download.get('docId'), name)
if not os.path.isdir(os.path.join(storagepath, download.get('docId'))):
os.makedirs(os.path.join(
storagepath, download.get("docId")), exist_ok=True)
storagepath, download.get('docId')), exist_ok=True)

saved = 0
totalsize = int(obb.get("file").get("total_size"))
with open(obbpath, "wb") as obbf:
for chunk in obb.get("file").get("data"):
totalsize = int(obb.get('file').get('total_size'))
with open(obbpath, 'wb') as obbf:
for chunk in obb.get('file').get('data'):
obbf.write(chunk)
saved += len(chunk)
done = int(50 * saved / totalsize)
sys.stdout.write("\r[%s%s] %s%s (%s/%s)" % ("*" * done, " " * (50-done), int(
(saved/totalsize)*100), "%", sizeof_fmt(saved), sizeof_fmt(totalsize)))
print("")
print(colored("OBB file downloaded and stored at %s" % obbpath, "green"))
sys.stdout.write('\r[%s%s] %s%s (%s/%s)' % ('*' * done, ' ' * (50-done), int(
(saved/totalsize)*100), '%', sizeof_fmt(saved), sizeof_fmt(totalsize)))
print('')
print(colored('OBB file downloaded and stored at %s' % obbpath, 'green'))
except Exception as e:
print(colored(
"Download failed. gplaydl cannot download some apps that are paid or incompatible.", "red"))
'Download failed: %s' % str(e), 'red'))


def write_cache(gsfId, token):
if not os.path.exists(CACHEDIR):
os.makedirs(CACHEDIR, exist_ok=True)
info = {"gsfId": gsfId, "token": token}
pickle.dump(info, open(CACHEFILE, "wb"))
info = {'gsfId': gsfId, 'token': token}
pickle.dump(info, open(CACHEFILE, 'wb'))


def read_cache():
try:
with open(CACHEFILE, "rb") as f:
with open(CACHEFILE, 'rb') as f:
info = pickle.load(f)
except:
info = None
Expand All @@ -206,7 +206,7 @@ def do_login(server, email, password):
if cacheinfo:
# Sign in using cached info
try:
server.login(None, None, cacheinfo["gsfId"], cacheinfo["token"])
server.login(None, None, cacheinfo['gsfId'], cacheinfo['token'])
except:
refresh_cache(email, password)
else:
Expand All @@ -220,15 +220,15 @@ def main():
print(colored('Only Python 3.2.x & up is supported. Please uninstall gplaydl and re-install under Python 3.2.x or up.', 'yellow'))
sys.exit(1)

if args.action == "configure":
if args.action == 'configure':
configureauth()
sys.exit(0)

if args.action == "download":
if args.action == 'download':
if args.packageId:
downloadapp(packageId=args.packageId)
sys.exit(0)


if args.action not in ["download", "configure"]:
if args.action not in ['download', 'configure']:
ap.print_help()
9 changes: 4 additions & 5 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
certifi==2020.4.5.1
cffi==1.14.0
chardet==3.0.4
cryptography==3.2
cryptography==2.9
decorator==4.4.2
gpapidl==1.0.1
gplaydl==1.3.3
gpapidl==1.0.2
idna==2.9
protobuf==3.11.3
protobuf==3.14.0
pycparser==2.20
requests==2.23.0
six==1.14.0
termcolor==1.1.0
urllib3==1.25.9
urllib3==1.25.8
validators==0.14.3
17 changes: 14 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,19 @@
'gplaydl'
],
install_requires=[
'gpapidl',
'validators',
'termcolor'
'certifi==2020.4.5.1',
'cffi==1.14.0',
'chardet==3.0.4',
'cryptography==2.9',
'decorator==4.4.2',
'gpapidl==1.0.2',
'idna==2.9',
'protobuf==3.14.0',
'pycparser==2.20',
'requests==2.23.0',
'six==1.14.0',
'termcolor==1.1.0',
'urllib3==1.25.8',
'validators==0.14.3'
]
)

0 comments on commit c6f9313

Please sign in to comment.