apksearch 1.2.7__py3-none-any.whl → 1.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- apksearch/__init__.py +9 -1
- apksearch/cli.py +9 -1
- apksearch/sites/apkpure.py +59 -1
- apksearch/sites/aptoide.py +19 -3
- {apksearch-1.2.7.dist-info → apksearch-1.3.1.dist-info}/METADATA +4 -3
- apksearch-1.3.1.dist-info/RECORD +17 -0
- {apksearch-1.2.7.dist-info → apksearch-1.3.1.dist-info}/WHEEL +1 -1
- apksearch-1.2.7.dist-info/RECORD +0 -17
- {apksearch-1.2.7.dist-info → apksearch-1.3.1.dist-info}/entry_points.txt +0 -0
- {apksearch-1.2.7.dist-info → apksearch-1.3.1.dist-info/licenses}/LICENSE +0 -0
- {apksearch-1.2.7.dist-info → apksearch-1.3.1.dist-info}/top_level.txt +0 -0
apksearch/__init__.py
CHANGED
@@ -6,4 +6,12 @@ from .sites.apkfab import APKFab
|
|
6
6
|
from .sites.apkad import APKad
|
7
7
|
from .sites.aptoide import Aptoide
|
8
8
|
|
9
|
-
__all__ = [
|
9
|
+
__all__ = [
|
10
|
+
"APKPure",
|
11
|
+
"APKMirror",
|
12
|
+
"AppTeka",
|
13
|
+
"APKCombo",
|
14
|
+
"APKFab",
|
15
|
+
"APKad",
|
16
|
+
"Aptoide",
|
17
|
+
]
|
apksearch/cli.py
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
import argparse
|
2
2
|
|
3
3
|
from collections.abc import Callable
|
4
|
-
from apksearch import
|
4
|
+
from apksearch import (
|
5
|
+
APKPure,
|
6
|
+
APKMirror,
|
7
|
+
AppTeka,
|
8
|
+
APKCombo,
|
9
|
+
APKFab,
|
10
|
+
APKad,
|
11
|
+
Aptoide,
|
12
|
+
)
|
5
13
|
from requests.exceptions import ConnectionError, ConnectTimeout
|
6
14
|
|
7
15
|
# Color codes
|
apksearch/sites/apkpure.py
CHANGED
@@ -32,6 +32,19 @@ class APKPure:
|
|
32
32
|
self.cdn_url = "https://d.cdnpure.com/b/APK/"
|
33
33
|
self.cdn_version = "?version="
|
34
34
|
self.search_url = self.base_url + "/search?q="
|
35
|
+
self.api_url = "https://tapi.pureapk.com/v3/get_app_his_version"
|
36
|
+
self.api_headers = {
|
37
|
+
"User-Agent-WebView": "Mozilla/5.0 (Linux; Android 13; Pixel 5 Build/TQ3A.230901.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/132.0.6834.122 Safari/537.36",
|
38
|
+
"User-Agent": "Dalvik/2.1.0 (Linux; U; Android 13; Pixel 5 Build/TQ3A.230901.001); APKPure/3.20.34 (Aegon)",
|
39
|
+
"Ual-Access-Businessid": "projecta",
|
40
|
+
"Ual-Access-ProjectA": """{"device_info":{"abis":["x86_64","arm64-v8a","x86","armeabi-v7a","armeabi"],"android_id":"50f838123d9a9c94","brand":"google","country":"United States","country_code":"US","imei":"","language":"en-US","manufacturer":"Google","mode":"Pixel 5","os_ver":"33","os_ver_name":"13","platform":1,"product":"redfin","screen_height":1080,"screen_width":1920},"host_app_info":{"build_no":"468","channel":"","md5":"6756e53158d6f6c013650a40d8f1147b","pkg_name":"com.apkpure.aegon","sdk_ver":"3.20.34","version_code":3203427,"version_name":"3.20.34"}}""",
|
41
|
+
"Ual-Access-ExtInfo": """{"ext_info":"{\"gaid\":\"\",\"oaid\":\"\"}","lbs_info":{"accuracy":0.0,"city":"","city_code":0,"country":"","country_code":"","district":"","latitude":0.0,"longitude":0.0,"province":"","street":""}}""",
|
42
|
+
"Ual-Access-Sequence": "",
|
43
|
+
"Ual-Access-Nonce": "21448252",
|
44
|
+
"Ual-Access-Timestamp": "1738560597165",
|
45
|
+
"Connection": "Keep-Alive",
|
46
|
+
"Accept-Encoding": "gzip",
|
47
|
+
}
|
35
48
|
self.headers = {
|
36
49
|
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
37
50
|
"accept-language": "en-US,en;q=0.9,en-IN;q=0.8",
|
@@ -52,6 +65,40 @@ class APKPure:
|
|
52
65
|
}
|
53
66
|
self.session = requests.Session()
|
54
67
|
|
68
|
+
def _api_search(self) -> None | tuple[str, list[tuple[str, str]]]:
|
69
|
+
"""
|
70
|
+
Attempts to fetch app information using API.
|
71
|
+
|
72
|
+
Returns:
|
73
|
+
None: If API request fails or no data found
|
74
|
+
tuple[str, list[tuple[str, str]]]: App title and list of (version, download_url) tuples
|
75
|
+
"""
|
76
|
+
try:
|
77
|
+
params = {"package_name": self.pkg_name, "hl": "en"}
|
78
|
+
response = self.session.get(
|
79
|
+
self.api_url, headers=self.api_headers, params=params
|
80
|
+
)
|
81
|
+
data = response.json()
|
82
|
+
|
83
|
+
if not data.get("version_list"):
|
84
|
+
return None
|
85
|
+
|
86
|
+
versions_info = []
|
87
|
+
title = None
|
88
|
+
|
89
|
+
for version in data["version_list"]:
|
90
|
+
version_name = version["version_name"]
|
91
|
+
if not title:
|
92
|
+
title = version["title"]
|
93
|
+
if version.get("asset", {}).get("urls"):
|
94
|
+
download_url = version["asset"]["urls"][0]
|
95
|
+
versions_info.append((version_name, download_url))
|
96
|
+
|
97
|
+
return (title, versions_info) if title and versions_info else None
|
98
|
+
|
99
|
+
except Exception:
|
100
|
+
return None
|
101
|
+
|
55
102
|
def search_apk(self) -> None | tuple[str, str]:
|
56
103
|
"""
|
57
104
|
Searches for the APK on APKPure and returns the title and link if found.
|
@@ -83,7 +130,7 @@ class APKPure:
|
|
83
130
|
try:
|
84
131
|
location = response.headers.get("Location")
|
85
132
|
except AttributeError:
|
86
|
-
|
133
|
+
location = None
|
87
134
|
if location:
|
88
135
|
if location == "https://apkpure.com":
|
89
136
|
return None
|
@@ -97,6 +144,13 @@ class APKPure:
|
|
97
144
|
if content:
|
98
145
|
apk_title = content.split("filename=")[1].strip('"').split("_")[0]
|
99
146
|
return apk_title, location
|
147
|
+
|
148
|
+
api_result = self._api_search()
|
149
|
+
if api_result:
|
150
|
+
title, versions = api_result
|
151
|
+
if versions:
|
152
|
+
return title, versions[0][1]
|
153
|
+
|
100
154
|
return None
|
101
155
|
|
102
156
|
def find_versions(self, apk_link: str) -> list[tuple[str, str]]:
|
@@ -110,6 +164,10 @@ class APKPure:
|
|
110
164
|
list[tuple[str, str]]: A list of tuples, where each tuple contains the version number
|
111
165
|
and its corresponding download link. If no versions are found, an empty list is returned.
|
112
166
|
"""
|
167
|
+
api_result = self._api_search()
|
168
|
+
if api_result:
|
169
|
+
return api_result[1]
|
170
|
+
|
113
171
|
versions_info = []
|
114
172
|
if apk_link.startswith(self.base_url):
|
115
173
|
url = apk_link + "/versions"
|
apksearch/sites/aptoide.py
CHANGED
@@ -29,7 +29,7 @@ class Aptoide:
|
|
29
29
|
def __init__(self, pkg_name: str):
|
30
30
|
self.pkg_name = pkg_name
|
31
31
|
self.api_url = "https://ws75.aptoide.com/api/7"
|
32
|
-
self.search_url = f"{self.api_url}/apps/search
|
32
|
+
self.search_url = f"{self.api_url}/apps/search"
|
33
33
|
self.headers = {
|
34
34
|
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
35
35
|
"accept-language": "en-US,en;q=0.9,en-IN;q=0.8",
|
@@ -48,6 +48,20 @@ class Aptoide:
|
|
48
48
|
"upgrade-insecure-requests": "1",
|
49
49
|
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0",
|
50
50
|
}
|
51
|
+
self.params = {
|
52
|
+
"cdn": "web",
|
53
|
+
"q": "bXlDUFU9YXJtNjQtdjhhLGFybWVhYmktdjdhLGFybWVhYmkmbGVhbmJhY2s9MA",
|
54
|
+
"aab": "1",
|
55
|
+
"mature": "false",
|
56
|
+
"language": "en_US",
|
57
|
+
"country": "US",
|
58
|
+
"not_apk_tags": "",
|
59
|
+
"query": self.pkg_name,
|
60
|
+
"limit": "1",
|
61
|
+
"offset": "0",
|
62
|
+
"origin": "SITE",
|
63
|
+
"store_name": "aptoide-web",
|
64
|
+
}
|
51
65
|
self.session = requests.Session()
|
52
66
|
|
53
67
|
def search_apk(self) -> None | tuple[str, str]:
|
@@ -59,8 +73,10 @@ class Aptoide:
|
|
59
73
|
tuple[str, str]: A tuple containing the title and link of the matching APK if found.
|
60
74
|
"""
|
61
75
|
pkg_name = self.pkg_name
|
62
|
-
url = self.search_url
|
63
|
-
response: requests.Response = self.session.get(
|
76
|
+
url = self.search_url
|
77
|
+
response: requests.Response = self.session.get(
|
78
|
+
url, headers=self.headers, params=self.params
|
79
|
+
)
|
64
80
|
data = response.json()
|
65
81
|
if data and data["info"]["status"] == "OK":
|
66
82
|
lis = data["datalist"]["list"]
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: apksearch
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.3.1
|
4
4
|
Summary: Search for apks on varius websites
|
5
5
|
Author-email: Abhi <allinoneallinone00@gmail.com>
|
6
6
|
License: MIT License
|
@@ -49,6 +49,7 @@ Provides-Extra: dev
|
|
49
49
|
Requires-Dist: pytest>=7.4.3; extra == "dev"
|
50
50
|
Requires-Dist: black>=23.12.1; extra == "dev"
|
51
51
|
Requires-Dist: flake8>=6.1.0; extra == "dev"
|
52
|
+
Dynamic: license-file
|
52
53
|
|
53
54
|
<h1 align="center">apksearch</h1>
|
54
55
|
|
@@ -186,7 +187,7 @@ pytest
|
|
186
187
|
## Acknowledgements
|
187
188
|
|
188
189
|
- [APKUpdater](https://github.com/rumboalla/apkupdater) for APKMirror API.
|
189
|
-
|
190
|
+
~~- [apkeep](https://github.com/EFForg/apkeep) for APKPure API.~~ (not used anymore)
|
190
191
|
|
191
192
|
## License
|
192
193
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
apksearch/__init__.py,sha256=06RpnjvNr-B_sXsF3O4KFqNr34A3UA0Gfyz426RffsA,365
|
2
|
+
apksearch/__main__.py,sha256=MSmt_5Xg84uHqzTN38JwgseJK8rsJn_11A8WD99VtEo,61
|
3
|
+
apksearch/cli.py,sha256=RIl40MRL3YQZ_4yQwFTaX11ujJtWy9s8H-wWfY6HRFU,8835
|
4
|
+
apksearch/sites/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
+
apksearch/sites/apkad.py,sha256=x5nnI20Rj1LysZQc7-vFEbooxXb0vkmHzFpHoUvF_SA,4811
|
6
|
+
apksearch/sites/apkcombo.py,sha256=AiJhSb0subQLb51dr8MQaxgeEZ77wI99InfigYfrcl4,4718
|
7
|
+
apksearch/sites/apkfab.py,sha256=5f0fOBmQk0E30NcVE2cF80soJqI5ziOukU6_xMPtgFQ,5502
|
8
|
+
apksearch/sites/apkmirror.py,sha256=IpS6r7ovM3g2dZrkR_a9zQpHy-jqrU2nJ3ykVkWxers,3127
|
9
|
+
apksearch/sites/apkpure.py,sha256=YrM3uA1abrVWObG_Dzk2pMH9VBAsBCpZYgPGEF--7eU,8923
|
10
|
+
apksearch/sites/appteka.py,sha256=in04JYF043n0fUvBW1QQeXnNbYekGUIh4qeame951nA,6372
|
11
|
+
apksearch/sites/aptoide.py,sha256=5RruPDwyo5z0E2XesX4Mi41ONdn26SxN0dH36eRolNQ,4816
|
12
|
+
apksearch-1.3.1.dist-info/licenses/LICENSE,sha256=Icu9iAY9cAaraq-HaAk8aWpXS1nE-3U_wfaOhN-HQUw,1061
|
13
|
+
apksearch-1.3.1.dist-info/METADATA,sha256=y5FIlmIjoIO2jTxYljjwCwB1QSAhIneyK09Vn-a7toI,8230
|
14
|
+
apksearch-1.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
15
|
+
apksearch-1.3.1.dist-info/entry_points.txt,sha256=FeAPgNPSU1tCwQNaKAmk6eQYbMHtsltcgeWSGUTxu0k,49
|
16
|
+
apksearch-1.3.1.dist-info/top_level.txt,sha256=VguZMODhlXWwDyJJNJms5syJ4EHmWSQOS45J9I5Cv5o,10
|
17
|
+
apksearch-1.3.1.dist-info/RECORD,,
|
apksearch-1.2.7.dist-info/RECORD
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
apksearch/__init__.py,sha256=ximCGw08I0PBhA9IWmkLyV5TJRKC_77MM55t8jCXnrk,334
|
2
|
-
apksearch/__main__.py,sha256=MSmt_5Xg84uHqzTN38JwgseJK8rsJn_11A8WD99VtEo,61
|
3
|
-
apksearch/cli.py,sha256=y2j6dssYUrSSLfhiLJgTDElXLbyOU4g4d8njQI8ioow,8802
|
4
|
-
apksearch/sites/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
-
apksearch/sites/apkad.py,sha256=x5nnI20Rj1LysZQc7-vFEbooxXb0vkmHzFpHoUvF_SA,4811
|
6
|
-
apksearch/sites/apkcombo.py,sha256=AiJhSb0subQLb51dr8MQaxgeEZ77wI99InfigYfrcl4,4718
|
7
|
-
apksearch/sites/apkfab.py,sha256=5f0fOBmQk0E30NcVE2cF80soJqI5ziOukU6_xMPtgFQ,5502
|
8
|
-
apksearch/sites/apkmirror.py,sha256=IpS6r7ovM3g2dZrkR_a9zQpHy-jqrU2nJ3ykVkWxers,3127
|
9
|
-
apksearch/sites/apkpure.py,sha256=7IUY4u6q6ga_8CFQ1DCaeU_WS2xE70T_7PUU0o20NCk,5941
|
10
|
-
apksearch/sites/appteka.py,sha256=in04JYF043n0fUvBW1QQeXnNbYekGUIh4qeame951nA,6372
|
11
|
-
apksearch/sites/aptoide.py,sha256=CtLm5ItHZZ8YczcexnoVDePA379wJfM_I5OuQk1tkkk,4348
|
12
|
-
apksearch-1.2.7.dist-info/LICENSE,sha256=Icu9iAY9cAaraq-HaAk8aWpXS1nE-3U_wfaOhN-HQUw,1061
|
13
|
-
apksearch-1.2.7.dist-info/METADATA,sha256=YybBwp4yCe0mLkoC681aaRGPYcv9BTe40P1MR21oyXg,8185
|
14
|
-
apksearch-1.2.7.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
15
|
-
apksearch-1.2.7.dist-info/entry_points.txt,sha256=FeAPgNPSU1tCwQNaKAmk6eQYbMHtsltcgeWSGUTxu0k,49
|
16
|
-
apksearch-1.2.7.dist-info/top_level.txt,sha256=VguZMODhlXWwDyJJNJms5syJ4EHmWSQOS45J9I5Cv5o,10
|
17
|
-
apksearch-1.2.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|