mirror of
https://github.com/FliegendeWurst/googleplay-api.git
synced 2024-11-22 12:54:58 +00:00
parent
2ab7ce09c6
commit
9d0d14450b
126
gpapi/config.py
126
gpapi/config.py
@ -19,20 +19,14 @@ GOOGLE_PUBKEY = "AAAAgMom/1a/v0lblO2Ubrt60J2gcuXSljGFQXgcyZWveWLEwo6prwgi3iJIZdo
|
||||
# if you want to add another phone, just create another section in
|
||||
# the file. Some configurations for common phones can be found here:
|
||||
# https://github.com/yeriomin/play-store-api/tree/master/src/main/resources
|
||||
filepath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
||||
'device.properties')
|
||||
|
||||
if VERSION == 2:
|
||||
config = ConfigParser.ConfigParser()
|
||||
else:
|
||||
config = configparser.ConfigParser()
|
||||
|
||||
filepath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
||||
'device.properties')
|
||||
config.read(filepath)
|
||||
device = {}
|
||||
# initialize device, because we need to setup UserAgent
|
||||
# before the end of login method. If the login defines a different
|
||||
# device, it won't cause conflicts
|
||||
for (key, value) in config.items('angler'):
|
||||
device[key] = value
|
||||
|
||||
|
||||
def getDevicesCodenames():
|
||||
@ -50,40 +44,58 @@ def getDevicesReadableNames():
|
||||
return output
|
||||
|
||||
|
||||
def getUserAgent():
|
||||
class DeviceBuilder(object):
|
||||
|
||||
def __init__(self, device):
|
||||
self.device = {}
|
||||
for (key, value) in config.items(device):
|
||||
self.device[key] = value
|
||||
|
||||
def getUserAgent(self):
|
||||
return ("Android-Finsky/8.1.72.S-all [6] [PR] 165478484 ("
|
||||
"api=3"
|
||||
",versionCode={versionCode}"
|
||||
",sdk={sdk}"
|
||||
",device={device}"
|
||||
",hardware={hardware}"
|
||||
",product={product}").format(versionCode=device['vending.version'],
|
||||
sdk=device['build.version.sdk_int'],
|
||||
device=device['build.device'],
|
||||
hardware=device['build.hardware'],
|
||||
product=device['build.product'])
|
||||
",product={product}"
|
||||
"").format(versionCode=self.device['vending.version'],
|
||||
sdk=self.device['build.version.sdk_int'],
|
||||
device=self.device['build.device'],
|
||||
hardware=self.device['build.hardware'],
|
||||
product=self.device['build.product'])
|
||||
|
||||
def getAndroidCheckinRequest(self):
|
||||
request = googleplay_pb2.AndroidCheckinRequest()
|
||||
request.id = 0
|
||||
request.checkin.CopyFrom(self.getAndroidCheckin())
|
||||
request.locale = LANG
|
||||
request.timeZone = TIMEZONE
|
||||
request.version = 3
|
||||
request.deviceConfiguration.CopyFrom(self.getDeviceConfig())
|
||||
request.fragment = 0
|
||||
return request
|
||||
|
||||
def getDeviceConfig():
|
||||
libList = device['sharedlibraries'].split(",")
|
||||
featureList = device['features'].split(",")
|
||||
localeList = device['locales'].split(",")
|
||||
glList = device['gl.extensions'].split(",")
|
||||
platforms = device['platforms'].split(",")
|
||||
def getDeviceConfig(self):
|
||||
libList = self.device['sharedlibraries'].split(",")
|
||||
featureList = self.device['features'].split(",")
|
||||
localeList = self.device['locales'].split(",")
|
||||
glList = self.device['gl.extensions'].split(",")
|
||||
platforms = self.device['platforms'].split(",")
|
||||
|
||||
hasFiveWayNavigation = (device['hasfivewaynavigation'] == 'true')
|
||||
hasHardKeyboard = (device['hashardkeyboard'] == 'true')
|
||||
hasFiveWayNavigation = (self.device['hasfivewaynavigation'] == 'true')
|
||||
hasHardKeyboard = (self.device['hashardkeyboard'] == 'true')
|
||||
deviceConfig = googleplay_pb2.DeviceConfigurationProto()
|
||||
deviceConfig.touchScreen = int(device['touchscreen'])
|
||||
deviceConfig.keyboard = int(device['keyboard'])
|
||||
deviceConfig.navigation = int(device['navigation'])
|
||||
deviceConfig.screenLayout = int(device['screenlayout'])
|
||||
deviceConfig.touchScreen = int(self.device['touchscreen'])
|
||||
deviceConfig.keyboard = int(self.device['keyboard'])
|
||||
deviceConfig.navigation = int(self.device['navigation'])
|
||||
deviceConfig.screenLayout = int(self.device['screenlayout'])
|
||||
deviceConfig.hasHardKeyboard = hasHardKeyboard
|
||||
deviceConfig.hasFiveWayNavigation = hasFiveWayNavigation
|
||||
deviceConfig.screenDensity = int(device['screen.density'])
|
||||
deviceConfig.screenWidth = int(device['screen.width'])
|
||||
deviceConfig.screenHeight = int(device['screen.height'])
|
||||
deviceConfig.glEsVersion = int(device['gl.version'])
|
||||
deviceConfig.screenDensity = int(self.device['screen.density'])
|
||||
deviceConfig.screenWidth = int(self.device['screen.width'])
|
||||
deviceConfig.screenHeight = int(self.device['screen.height'])
|
||||
deviceConfig.glEsVersion = int(self.device['gl.version'])
|
||||
for x in platforms:
|
||||
deviceConfig.nativePlatform.append(x)
|
||||
for x in libList:
|
||||
@ -96,46 +108,30 @@ def getDeviceConfig():
|
||||
deviceConfig.glExtension.append(x)
|
||||
return deviceConfig
|
||||
|
||||
|
||||
def getAndroidBuild():
|
||||
def getAndroidBuild(self):
|
||||
androidBuild = googleplay_pb2.AndroidBuildProto()
|
||||
androidBuild.id = device['build.fingerprint']
|
||||
androidBuild.product = device['build.hardware']
|
||||
androidBuild.carrier = device['build.brand']
|
||||
androidBuild.radio = device['build.radio']
|
||||
androidBuild.bootloader = device['build.bootloader']
|
||||
androidBuild.device = device['build.device']
|
||||
androidBuild.sdkVersion = int(device['build.version.sdk_int'])
|
||||
androidBuild.model = device['build.model']
|
||||
androidBuild.manufacturer = device['build.manufacturer']
|
||||
androidBuild.buildProduct = device['build.product']
|
||||
androidBuild.client = device['client']
|
||||
androidBuild.id = self.device['build.fingerprint']
|
||||
androidBuild.product = self.device['build.hardware']
|
||||
androidBuild.carrier = self.device['build.brand']
|
||||
androidBuild.radio = self.device['build.radio']
|
||||
androidBuild.bootloader = self.device['build.bootloader']
|
||||
androidBuild.device = self.device['build.device']
|
||||
androidBuild.sdkVersion = int(self.device['build.version.sdk_int'])
|
||||
androidBuild.model = self.device['build.model']
|
||||
androidBuild.manufacturer = self.device['build.manufacturer']
|
||||
androidBuild.buildProduct = self.device['build.product']
|
||||
androidBuild.client = self.device['client']
|
||||
androidBuild.otaInstalled = False
|
||||
androidBuild.timestamp = int(time.time())
|
||||
androidBuild.googleServices = int(device['gsf.version'])
|
||||
androidBuild.googleServices = int(self.device['gsf.version'])
|
||||
return androidBuild
|
||||
|
||||
|
||||
def getAndroidCheckin():
|
||||
def getAndroidCheckin(self):
|
||||
androidCheckin = googleplay_pb2.AndroidCheckinProto()
|
||||
androidCheckin.build.CopyFrom(getAndroidBuild())
|
||||
androidCheckin.build.CopyFrom(self.getAndroidBuild())
|
||||
androidCheckin.lastCheckinMsec = 0
|
||||
androidCheckin.cellOperator = device['celloperator']
|
||||
androidCheckin.simOperator = device['simoperator']
|
||||
androidCheckin.roaming = device['roaming']
|
||||
androidCheckin.cellOperator = self.device['celloperator']
|
||||
androidCheckin.simOperator = self.device['simoperator']
|
||||
androidCheckin.roaming = self.device['roaming']
|
||||
androidCheckin.userNumber = 0
|
||||
return androidCheckin
|
||||
|
||||
|
||||
def getAndroidCheckinRequest(device_codename):
|
||||
for (key, value) in config.items(device_codename):
|
||||
device[key] = value
|
||||
request = googleplay_pb2.AndroidCheckinRequest()
|
||||
request.id = 0
|
||||
request.checkin.CopyFrom(getAndroidCheckin())
|
||||
request.locale = LANG
|
||||
request.timeZone = TIMEZONE
|
||||
request.version = 3
|
||||
request.deviceConfiguration.CopyFrom(getDeviceConfig())
|
||||
request.fragment = 0
|
||||
return request
|
||||
|
@ -46,11 +46,12 @@ class GooglePlayAPI(object):
|
||||
AUTHURL = BASE + "auth"
|
||||
ACCOUNT = "HOSTED_OR_GOOGLE"
|
||||
|
||||
def __init__(self, debug=False):
|
||||
def __init__(self, debug=False, device_codename='bacon'):
|
||||
self.authSubToken = None
|
||||
self.gsfId = None
|
||||
self.lang = config.LANG
|
||||
self.debug = debug
|
||||
self.deviceBuilder = config.DeviceBuilder(device_codename)
|
||||
|
||||
def encrypt_password(self, login, passwd):
|
||||
"""Encrypt the password using the google publickey, using
|
||||
@ -87,7 +88,7 @@ class GooglePlayAPI(object):
|
||||
headers = {
|
||||
"Accept-Language": config.LANG.replace('_', '-'),
|
||||
"X-DFE-Encoded-Targets": config.DFE_TARGETS,
|
||||
"User-Agent": config.getUserAgent()
|
||||
"User-Agent": self.deviceBuilder.getUserAgent()
|
||||
}
|
||||
if self.gsfId is not None:
|
||||
headers["X-DFE-Device-Id"] = "{0:x}".format(self.gsfId)
|
||||
@ -95,11 +96,11 @@ class GooglePlayAPI(object):
|
||||
headers["Authorization"] = "GoogleLogin auth=%s" % self.authSubToken
|
||||
return headers
|
||||
|
||||
def checkin(self, email, ac2dmToken, device_codename):
|
||||
def checkin(self, email, ac2dmToken):
|
||||
headers = self.getDefaultHeaders()
|
||||
headers["Content-Type"] = "application/x-protobuffer"
|
||||
|
||||
request = config.getAndroidCheckinRequest(device_codename)
|
||||
request = self.deviceBuilder.getAndroidCheckinRequest()
|
||||
|
||||
stringRequest = request.SerializeToString()
|
||||
res = requests.post(self.CHECKINURL, data=stringRequest,
|
||||
@ -125,7 +126,7 @@ class GooglePlayAPI(object):
|
||||
*device.properties* to the google account. Default device is a Google Nexus 6P"""
|
||||
|
||||
upload = googleplay_pb2.UploadDeviceConfigRequest()
|
||||
upload.deviceConfiguration.CopyFrom(config.getDeviceConfig())
|
||||
upload.deviceConfiguration.CopyFrom(self.deviceBuilder.getDeviceConfig())
|
||||
headers = self.getDefaultHeaders()
|
||||
headers["X-DFE-Enabled-Experiments"] = "cl:billing.select_add_instrument_by_default"
|
||||
headers["X-DFE-Unsupported-Experiments"] = "nocache:billing.use_charging_poller,market_emails,buyer_currency,prod_baseline,checkin.set_asset_paid_app_field,shekel_test,content_ratings,buyer_currency_in_app,nocache:encrypted_apk,recent_changes"
|
||||
@ -137,8 +138,7 @@ class GooglePlayAPI(object):
|
||||
headers=headers, verify=ssl_verify)
|
||||
googleplay_pb2.ResponseWrapper.FromString(res.content)
|
||||
|
||||
def login(self, email=None, password=None, gsfId=None,
|
||||
authSubToken=None, device_codename='bacon'):
|
||||
def login(self, email=None, password=None, gsfId=None, authSubToken=None):
|
||||
"""Login to your Google Account.
|
||||
For first time login you should provide:
|
||||
* email
|
||||
@ -185,7 +185,7 @@ class GooglePlayAPI(object):
|
||||
else:
|
||||
raise LoginError("Auth token not found.")
|
||||
|
||||
self.gsfId = self.checkin(email, ac2dmToken, device_codename)
|
||||
self.gsfId = self.checkin(email, ac2dmToken)
|
||||
if self.debug:
|
||||
print("Google Services Framework Id: %s" % "{0:x}".format(self.gsfId))
|
||||
self.getAuthSubToken(email, encryptedPass)
|
||||
@ -496,6 +496,9 @@ class GooglePlayAPI(object):
|
||||
return self.delivery(packageName, versionCode,
|
||||
offerType, dlToken, progress_bar=progress_bar)
|
||||
|
||||
def changeDevice(self, device_codename):
|
||||
self.deviceBuilder = config.DeviceBuilder(device_codename)
|
||||
|
||||
@staticmethod
|
||||
def getDevicesCodenames():
|
||||
return config.getDevicesCodenames()
|
||||
|
Loading…
Reference in New Issue
Block a user