ImranR98 / Obtainium

Get Android app updates straight from the source.
https://obtainium.imranr.dev
GNU General Public License v3.0
8.16k stars 178 forks source link

Add Support for RuStore as a Source for App Downloads in Obtainium #1593

Open trattaa opened 6 months ago

trattaa commented 6 months ago

Describe the Feature I propose adding RuStore as a new source for downloading and updating Android applications through Obtainium. RuStore is a popular Russian app store, and integrating it would benefit users by providing direct access to apps available in this market.

Implementation Reference A method to retrieve app version information and download links via the RuStore API can be found here: RuStore API Implementation. This implementation details how to fetch application details and initiate downloads correctly.

Example RuStore App Link An example of a RuStore app listing is: Telegram on RuStore

Implementation Details Below is the content from rustore.py, which outlines the method to obtain app details and download APKs from RuStore.

import logging
import os

import requests

logger = logging.getLogger(__name__)

def get_app_info(package_name):
    req = requests.get(f'https://backapi.rustore.ru/applicationData/overallInfo/{package_name}')
    if req.status_code == 200:
        body_info = req.json()['body']
        logger.info(f"Rustore - Successfully found app with package name: {package_name},"
                    f" version:{body_info['versionName']}, company: {body_info['companyName']}")
    else:
        raise RuntimeError(f'Rustore - Failed to get application info. Request return status code: {req.status_code}')

    headers = {
        'Content-Type': 'application/json; charset=utf-8'
    }
    body = {
        'appId': body_info['appId'],
        'firstInstall': True
    }
    download_link_resp = requests.post('https://backapi.rustore.ru/applicationData/download-link',
                                       headers=headers, json=body)
    if req.status_code == 200:
        download_link = download_link_resp.json()['body']['apkUrl']
    else:
        raise RuntimeError(f'Rustore - Failed to get application download link.'
                           f' Request return status code: {req.status_code}')

    return {
        'integration_type': 'rustore',
        'download_url': download_link,
        'package_name': body_info['packageName'],
        'version_name': body_info['versionName'],
        'version_code': body_info['versionCode'],
        'min_sdk_version': body_info['minSdkVersion'],
        'max_sdk_version': body_info['maxSdkVersion'],
        'target_sdk_version': body_info['targetSdkVersion'],
        'file_size': body_info['fileSize'],
        'icon_url': body_info['iconUrl']
    }

def rustore_download_app(package_name, download_path):
    app_info = get_app_info(package_name)
    logger.info('Rustore - Start downloading application')
    r = requests.get(app_info['download_url'])
    if r.status_code == 401:
        raise RuntimeError(f'Rustore - Failed to download application. '
                           f'Something goes wrong. Request return status code: {r.status_code}')

    file_path = f"{download_path}/{app_info['package_name']}-{app_info['version_name']}.apk"

    if not os.path.exists(download_path):
        os.mkdir(download_path)
        logger.info(f'Rustore - Creating directory {download_path} for downloading app from Rustore')

    f = open(file_path, 'wb')
    for chunk in r.iter_content(chunk_size=512 * 1024):
        if chunk:
            f.write(chunk)
    f.close()
    logger.info(f'Rustore - Apk was downloaded from rustore to {file_path}')

    return file_path

Additional Context For methods related to other distribution platforms like Huawei AppGallery, AppCenter, rumarket, and Google Play, please refer to the following directory: Distribution Systems Directory

This addition would align with Obtainium's goal of fetching Android app updates directly from their sources, providing users with a broader range of app stores to choose from.

DwainZwerg commented 6 months ago

I have a question about the Google Play download at https://github.com/Dynamic-Mobile-Security/mdast-cli/tree/main/mdast_cli/distribution_systems. According to the description, you have to switch off 2FA. As far as I know, this is no longer possible with Google.

re7gog commented 5 months ago

I want to do it because 1) thought about it because need it for apps like Сбербанк, but didn't know where to start 2) know python better than any other prog language (but again - later)

lastpsyfjord commented 4 weeks ago

This opportunity with RuStore is very necessary

iamgitcat commented 4 weeks ago

I have only 1 single app available exclusively in RuStore and I use this script to get it.

oldnomad commented 4 weeks ago

I've collected info about installation from RuStore in a doc. Not all API is known, but it seems sufficient to implement what's needed by Obtainium.