Exemple #1
0
def init_api(acct_email, acct_password, gsf, auth_sub_token=None, max_attempts=15, cooldown_secs=10):
    global api
    assert max_attempts > 0, 'max_attempts was %d, must be greater than 0' % max_attempts
    assert cooldown_secs > 0, 'cooldown_secs was %d, must be greater than 0' % cooldown_secs

    if api is None:
        # Ensure we have all the credentials we need
        assert acct_email is not None, 'Account email address is required'
        assert acct_password is not None, 'Account password is required'
        assert gsf is not None, 'Google Services Framework ID is required'

        # Authenticate the API, keep trying until it works
        api = GooglePlayAPI(androidId=gsf)

        for attempt in range(max(1, max_attempts)):
            attempt = attempt + 1
            try:
                login(email=acct_email, password=acct_password, authSubToken=auth_sub_token)
                logging.info('Successfully logged in as %s' % acct_email)
                return
            except LoginError as e:
                logging.warning('BadAuthentication on attempt %d/%d' % (attempt, max_attempts))

                if(attempt == max_attempts):
                    raise e

                logging.warning('Retrying authentication in %d seconds' % cooldown_secs)
                time.sleep(cooldown_secs)
 def _login(self):
     '''
     user android_id, user name and password or AUTH_TOKEN to login
     '''
     self._configTest()
     api = GooglePlayAPI(self._android_id)
     api.login(self._user, self._passwd, self._auth_token)
     return api
Exemple #3
0
 def __init__(self):
     try:
         creds = loadPlayStoreConfig()
         self.googleLogin = creds['GOOGLE_LOGIN']
         self.googlePassword = creds['GOOGLE_PASSWORD']
         self.androidID = creds['ANDROID_ID']
         self.authToken = creds['AUTH_TOKEN']
         self.api = GooglePlayAPI(self.androidID) # Login to the Play Store
     except Exception as e:
         prettyPrintError(e)
Exemple #4
0
def init_api(acct_email, acct_password, gsf):
    global api

    if api is None:
        # Ensure we have all the credentials we need
        assert acct_email is not None, 'Account email address is required'
        assert acct_password is not None, 'Account password is required'
        assert gsf is not None, 'Google Services Framework ID is required'

        # Authenticate the API
        api = GooglePlayAPI(androidId=gsf)
        api.login(email=acct_email, password=acct_password)
    def download_reference_apk(self):
        api = GooglePlayAPI(self.android_id)
        api.login(self.google_login, self.google_password)

        package = api.details(self.results['package'])
        doc = package.docV2
        version = doc.details.appDetails.versionCode
        offer_type = doc.offer[0].offerType

        ref_path = path.join(self.tmpdir, "ref.apk")
        data = api.download(self.results['package'], version, offer_type)
        with open(ref_path, "wb") as out:
            out.write(data)

        return ref_path
Exemple #6
0
    def __init__(self,
                 android_id=None,
                 username=None,
                 password=None,
                 auth_token=None,
                 proxy=None,
                 max_login_retries=10,
                 language=None,
                 debug=False):

        self._api = GooglePlayAPI(android_id, language, debug)

        self._username = username
        self._password = password
        self._auth_token = auth_token
        self._proxy = proxy
        self._max_login_retries = max_login_retries

        self._login_lock = Lock()
        self._logged_in = False
Exemple #7
0
ctr = None
nb_results = None
offset = None

if (len(sys.argv) >= 3):
    ctr = sys.argv[2]
if (len(sys.argv) >= 4):
    nb_results = sys.argv[3]
if (len(sys.argv) == 5):
    offset = sys.argv[4]

# read config from config.py
config = GooglePlayAPI.read_config()

# connect to GooglePlayStore
api = GooglePlayAPI(config['ANDROID_ID'])
api.login(config['GOOGLE_LOGIN'], config['GOOGLE_PASSWORD'],
          config['AUTH_TOKEN'])

try:
    message = api.list(cat, ctr, nb_results, offset)
except:
    print("Error: HTTP 500 - one of the provided parameters is invalid")
    sys.exit(1)

if (ctr is None):
    print("Subcategory ID", "Name", sep=config['SEPARATOR'])
    for doc in message.doc:
        print(helpers.str_compat(doc.docid),
              helpers.str_compat(doc.title),
              sep=config['SEPARATOR'])
Exemple #8
0
if (len(sys.argv) < 2):
    print "Usage: %s packagename [filename]"
    print "Download an app."
    print "If filename is not present, will write to packagename.apk."
    sys.exit(0)

packagename = sys.argv[1]

if (len(sys.argv) == 3):
    filename = sys.argv[2]
else:
    filename = packagename + ".apk"

# Connect
api = GooglePlayAPI(ANDROID_ID)
api.login(GOOGLE_LOGIN, GOOGLE_PASSWORD, AUTH_TOKEN)

# Get the version code and the offer type from the app details
m = api.details(packagename)
doc = m.docV2
vc = doc.details.appDetails.versionCode
ot = doc.offer[0].offerType

# Download
print "Downloading %s..." % sizeof_fmt(
    doc.details.appDetails.installationSize),
data = api.download(packagename, vc, ot)
open(filename, "wb").write(data)
print "Done"
Exemple #9
0
def main():
    logging.basicConfig(level=logging.INFO)

    parser = argparse.ArgumentParser(
        description='Unofficial PlayStore python interface', add_help=True)
    parser.add_argument('--request',
                        action="store",
                        dest='request_path',
                        help='Do a generic request, useful for deugging')
    parser.add_argument('--details',
                        action="store",
                        dest='package_to_detail',
                        help='Shows various details for the '
                        'given package')
    parser.add_argument('--search',
                        action="store",
                        dest='query',
                        help='Search the playstore')
    parser.add_argument('--similar',
                        action="store",
                        dest='package_similar',
                        help='Shows various packages similar '
                        'to the given package')
    parser.add_argument('--bulk-details',
                        action="store",
                        dest='packages_to_detail',
                        nargs='+',
                        type=str,
                        help='Shows details for a list of packages')
    list_group = parser.add_argument_group()
    list_group.add_argument(
        '--list',
        action="store_true",
        dest='list',
        help=
        'List the categories avilable on playstore. If --category is specified, lists the '
        'subcategories of the specified category. If --subcategory is also specified, lists '
        'the app in the subcategory.')
    list_group.add_argument(
        '--category',
        action="store",
        dest='cat',
        help='Specify a certain category (e.g. GAME_ARCADE)')
    list_group.add_argument(
        '--subcategory',
        action="store",
        dest='subcat',
        help='Specify a certain subcategory (e.g. apps_topselling_free)')
    group = parser.add_argument_group()
    group.add_argument('--download',
                       action="store",
                       dest='package_to_download',
                       help='Download the apk with given '
                       'package name')
    group.add_argument('-o',
                       action="store",
                       dest='output_folder',
                       help='(optional) Where to '
                       'save the downloaded apk')
    group.add_argument('--version',
                       action="store",
                       dest='version_code',
                       help='(optional) Version Code of the apk'
                       'to download (default: latest)')
    parser.add_argument('--remote-token',
                        action="store",
                        dest='token_url',
                        help='If the authentication token should be'
                        ' retrieved from a remote server')
    group_proxy = parser.add_argument_group()
    group_proxy.add_argument('--http-proxy',
                             action="store",
                             dest='http_proxy',
                             help='http proxy, ONLY used for'
                             'Play Store requests!')
    group_proxy.add_argument('--https-proxy',
                             action="store",
                             dest='https_proxy',
                             help='https proxy, ONLY used for'
                             'Play Store requests!')

    results = parser.parse_args()

    proxies = None
    if results.http_proxy:
        if proxies is None:
            proxies = {}
        proxies["http"] = results.http_proxy
    if results.https_proxy:
        if proxies is None:
            proxies = {}
        proxies["https"] = results.https_proxy
    global play_store
    play_store = GooglePlayAPI(throttle=True, proxies=proxies)
    token = None
    if results.token_url:
        response = requests.get(results.token_url)
        token = response.text
        print("Using auth token: {0}".format(token))
    play_store.login(authSubToken=token)

    if results.request_path:
        get_message(results.request_path)
        return

    if results.package_to_detail:
        get_details(results.package_to_detail)
        return

    if results.query:
        search(results.query)
        return

    if results.packages_to_detail:
        get_bulk_details(results.packages_to_detail)
        return

    if results.package_similar:
        get_similar(results.package_similar)
        return

    if results.list:
        list_category(results.cat, results.subcat)
        return

    if results.package_to_download:
        package = results.package_to_download
        version = results.version_code
        output_folder = results.output_folder
        if output_folder:
            os.path.join(output_folder, package + ".apk")
        else:
            output_folder = package + ".apk"
        download_apk(results.package_to_download, version, output_folder)
        return

    parser.print_help()
class GooglePlayApiTest(unittest.TestCase):
    api = GooglePlayAPI()

    @classmethod
    def setUpClass(cls):
        details = get_access_details()

        api = GooglePlayApiTest.api
        api.androidId = os.environ.get('ANDROID_ID', details.get('androidId'))

        last_error = None

        for _ in xrange(10):
            try:
                api.login(email=os.environ.get('GOOGLE_USERNAME',
                                               details.get('username')),
                          password=os.environ.get('GOOGLE_PASSWORD',
                                                  details.get('password')))
                break

            except LoginError as err:
                last_error = err
                time.sleep(0.2)

        else:
            raise last_error

    def test_search(self):
        results = self.api.search('hu.rycus')

        self.assertTrue(hasattr(results, 'doc'),
                        msg='Main doc object not found')
        self.assertGreater(len(results.doc), 0)

        document = results.doc[0]

        self.assertTrue(hasattr(document, 'child'),
                        msg='Child object not found')
        self.assertGreater(len(document.child), 0)

        for child in document.child:
            self._verify_item(child, simple=True)

    def test_details(self):
        details = self.api.details('hu.rycus.watchface.triangular')

        self.assertTrue(hasattr(details, 'docV2'),
                        msg='Main docV2 object not found')

        document = details.docV2

        self._verify_item(document, simple=False)

    def _verify_item(self, item, simple):
        for expected in ('title', 'creator', 'image', 'details',
                         'aggregateRating', 'shareUrl'):
            self.assertTrue(
                hasattr(item, expected),
                msg='Result document does not contain the %s field' % expected)

        if not simple:
            self.assertTrue(
                hasattr(item, 'descriptionHtml'),
                msg='Result document does not contain the descriptionHtml field'
            )

        for image in item.image:
            for expected in ('imageType', 'imageUrl'):
                self.assertTrue(hasattr(image, expected),
                                msg='Image does not contain the %s field' %
                                expected)

            if not simple:
                for expected in ('dimension', 'positionInSequence'):
                    self.assertTrue(hasattr(image, expected),
                                    msg='Image does not contain the %s field' %
                                    expected)

                dimension = image.dimension

                for expected in ('width', 'height'):
                    self.assertTrue(
                        hasattr(dimension, expected),
                        msg='Image dimension does not contain the %s field' %
                        expected)

        details = item.details

        self.assertTrue(hasattr(details, 'appDetails'),
                        msg='Result does not contain the appDetails object')

        app_details = details.appDetails

        for expected in ('packageName', 'uploadDate', 'numDownloads',
                         'versionCode'):
            self.assertTrue(hasattr(app_details, expected),
                            msg='App details do not contain the %s field' %
                            expected)

        if not simple:
            for expected in ('developerName', 'versionString',
                             'developerWebsite', 'recentChangesHtml'):
                self.assertTrue(hasattr(app_details, expected),
                                msg='App details do not contain the %s field' %
                                expected)

        rating = item.aggregateRating

        for expected in ('starRating', 'ratingsCount', 'commentCount',
                         'oneStarRatings', 'twoStarRatings',
                         'threeStarRatings', 'fourStarRatings',
                         'fiveStarRatings'):
            self.assertTrue(hasattr(rating, expected),
                            msg='App rating does not contain the %s field' %
                            expected)