diff --git a/README.md b/README.md new file mode 100644 index 0000000..95d1ac0 --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# apkdl +Search and download APKs from the command line + +# Install + +### Using pip + +``` +$ pip install apkdl +``` + +### Build from source + +``` +$ git clone https://github.com/sereneblue/apkdl +$ cd fts +$ python setup.py install +``` + +# Usage + +``` +$ apkdl firefox focus +Searching for: firefox focus +[00] Firefox Focus: The privacy browser + Developer: Mozilla +========================================= +[01] Firefox Browser fast & private + Developer: Mozilla +========================================= +[02] Dolphin Zero Incognito Browser - Private Browser + Developer: Dolphin Browser +========================================= +[03] Offline Survival Manual + Developer: ligi +========================================= +[04] DuckDuckGo Search & Stories + Developer: DuckDuckGo +========================================= +[05] ProtonMail - Encrypted Email + Developer: ProtonMail +========================================= +[06] Firefox Nightly for Developers (Unreleased) + Developer: Mozilla +========================================= +[07] AfterFocus + Developer: MotionOne +========================================= +[08] Find My Device + Developer: Google Inc. +========================================= +[09] Brave Browser: Fast AdBlocker + Developer: Brave Software +========================================= +[10] Todoist: To-Do List, Task List + Developer: Doist +========================================= +[11] Pale Moon web browser + Developer: Moonchild Productions +========================================= +[12] Firefox for Android Beta + Developer: Mozilla +========================================= +[13] Opera Free VPN - Unlimited VPN + Developer: OSL Networks +========================================= +[14] Samsung Internet Browser Beta + Developer: Samsung Electronics Co., Ltd. +========================================= +Which app would you like to download? +> 0 +Downloading org.mozilla.focus.apk ... +Download completed! +``` + +# Credits + +APKs are grabbed from https://apkpure.com. \ No newline at end of file diff --git a/apkdl/__init__.py b/apkdl/__init__.py new file mode 100644 index 0000000..d538f87 --- /dev/null +++ b/apkdl/__init__.py @@ -0,0 +1 @@ +__version__ = "1.0.0" \ No newline at end of file diff --git a/apkdl/__main__.py b/apkdl/__main__.py new file mode 100644 index 0000000..fcf0c6e --- /dev/null +++ b/apkdl/__main__.py @@ -0,0 +1,38 @@ +from apkdl.dl import download, search, APPS +import sys + +def main(): + if len(sys.argv) > 1: + query = " ".join(sys.argv[1:]) + + print('Searching for: {}'.format(query)) + + search(query) + + if len(APPS) > 0: + for idx, app in enumerate(APPS): + print("""[{:02d}] {}\n Developer: {}""".format(idx, app[0], app[1])) + print('=========================================') + + option = "" + while option == "": + option = input('Which app would you like to download?\n> ') + try: + if 0 <= int(option) < len(APPS): + option = int(option) + else: + print('That was not a valid option') + option = "" + except ValueError: + option = "" + + print('Downloading {}.apk ...'.format(APPS[option][2].split('/')[-1])) + + download(APPS[option][2]) + + print('Download completed!') + else: + print('No results') + else: + print('Missing input! Try:') + print('apkdl [app name]') \ No newline at end of file diff --git a/apkdl/dl.py b/apkdl/dl.py new file mode 100644 index 0000000..0706824 --- /dev/null +++ b/apkdl/dl.py @@ -0,0 +1,30 @@ +from bs4 import BeautifulSoup +from urllib.parse import quote_plus +import requests + +APPS = [] + +def download(link): + res = requests.get(link + '/download?from=details', headers={ + 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.5 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.5' + }).text + soup = BeautifulSoup(res, "html.parser").find('a', {'id':'download_link'}) + if soup['href']: + r = requests.get(soup['href'], stream=True, headers={ + 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.5 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.5' + }) + with open(link.split('/')[-1] + '.apk', 'wb') as file: + for chunk in r.iter_content(chunk_size=1024): + if chunk: + file.write(chunk) + +def search(query): + res = requests.get('https://apkpure.com/search?q={}®ion='.format(quote_plus(query)), headers={ + 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.5 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.5' + }).text + soup = BeautifulSoup(res, "html.parser") + for i in soup.find('div', {'id':'search-res'}).findAll('dl', {'class':'search-dl'}): + app = i.find('p', {'class':'search-title'}).find('a') + APPS.append((app.text, + i.findAll('p')[1].find('a').text, + 'https://apkpure.com' + app['href'])) \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..224a779 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[metadata] +description-file = README.md \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..4d739d8 --- /dev/null +++ b/setup.py @@ -0,0 +1,34 @@ +from setuptools import setup, find_packages +from apkdl import __version__ +import os + +setup( + name ='apkdl', + version = __version__, + description = 'Search and download APKs from the command line', + url = 'https://github.com/sereneblue/apkdl', + author = 'sereneblue', + license = "MIT", + packages = find_packages(), + classifiers = [ + 'Intended Audience :: Developers', + 'Environment :: Console', + 'Topic :: Utilities', + 'License :: OSI Approved :: MIT License', + 'Natural Language :: English', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + ], + keywords = ['android', 'apk', 'cli'], + install_requires = ['requests', 'beautifulsoup4'], + entry_points = { + 'console_scripts':[ + 'apkdl=apkdl.__main__:main' + ], + } +)