Full Code of lluni/twitter-apk for AI

master 4d468482adcd cached
16 files
20.8 KB
5.5k tokens
30 symbols
1 requests
Download .txt
Repository: lluni/twitter-apk
Branch: master
Commit: 4d468482adcd
Files: 16
Total size: 20.8 KB

Directory structure:
gitextract_pj8qm7k7/

├── .envrc
├── .github/
│   └── workflows/
│       ├── build.yaml
│       ├── daily.yaml
│       └── manual.yaml
├── .gitignore
├── README.md
├── apkmirror.py
├── build_variants.py
├── constants.py
├── download_bins.py
├── flake.nix
├── github.py
├── ks.keystore
├── main.py
├── pyproject.toml
└── utils.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .envrc
================================================
use flake


================================================
FILE: .github/workflows/build.yaml
================================================
name: Release

on:
  workflow_dispatch:

permissions:
  contents: write

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up java
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu' # See 'Supported distributions' for available options
          java-version: '17'

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          python-version: "3.13"
          enable-cache: true

      - name: Install dependencies
        run: uv sync --frozen

      - name: Try building
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          TG_TOKEN: ${{ secrets.TG_TOKEN }}
          TG_CHAT_ID: ${{ secrets.TG_CHAT_ID }}
          TG_THREAD_ID: ${{ secrets.TG_THREAD_ID }}
        run: |
          mkdir -p bins
          uv run main.py


================================================
FILE: .github/workflows/daily.yaml
================================================
name: Release - Daily

on:
  schedule:
    - cron: '0 0 * * *' # daily at 00:00 UTC
  workflow_dispatch:

permissions:
  contents: write

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up java
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu' # See 'Supported distributions' for available options
          java-version: '17'

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          python-version: "3.13"
          enable-cache: true

      - name: Install dependencies
        run: uv sync --frozen

      - name: Try building
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          TG_TOKEN: ${{ secrets.TG_TOKEN }}
          TG_CHAT_ID: ${{ secrets.TG_CHAT_ID }}
          TG_THREAD_ID: ${{ secrets.TG_THREAD_ID }}
        run: |
          mkdir -p bins
          uv run main.py


================================================
FILE: .github/workflows/manual.yaml
================================================
name: Release - manual

on:
  workflow_dispatch:
    inputs:
      version_input:
        description: 'Enter the version'
        required: true

permissions:
  contents: write

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up java
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu' # See 'Supported distributions' for available options
          java-version: '17'

      - name: Install uv
        uses: astral-sh/setup-uv@v7
        with:
          python-version: "3.13"
          enable-cache: true

      - name: Install dependencies
        run: uv sync --frozen

      - name: Try building
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          TG_TOKEN: ${{ secrets.TG_TOKEN }}
          TG_CHAT_ID: ${{ secrets.TG_CHAT_ID }}
          TG_THREAD_ID: ${{ secrets.TG_THREAD_ID }}
        run: |
          mkdir -p bins
          uv run main.py --m 1 --v ${{ github.event.inputs.version_input }}


================================================
FILE: .gitignore
================================================
.venv
__pycache__
test.py
.direnv


================================================
FILE: README.md
================================================
Apk builds of [piko](https://github.com/crimera/piko) patches

# Credits
- [revanced](https://github.com/ReVanced)
- [@REAndroid's APKEditor](https://github.com/REAndroid/APKEditor) - Used in merging split apks
- [j-hc](https://github.com/j-hc) - Project is inspired by j-hc's revanced builder template.


================================================
FILE: apkmirror.py
================================================
from dataclasses import dataclass
from typing import cast
from bs4 import BeautifulSoup, Tag
from utils import download, get_scraper


@dataclass
class Version:
    version: str
    link: str


@dataclass
class Variant:
    is_bundle: bool
    link: str
    architecture: str


@dataclass
class App:
    name: str
    link: str


class FailedToFindElement(Exception):
    def __init__(self, message=None) -> None:
        self.message = (
            f"Failed to find element{' ' + message if message is not None else ''}"  # noqa: E501
        )
        super().__init__(self.message)


class FailedToFetch(Exception):
    def __init__(self, url=None) -> None:
        self.message = f"Failed to fetch{' ' + url if url is not None else ''}"  # noqa: E501
        super().__init__(self.message)


def get_versions(url: str) -> list[Version]:
    """Get the latest version of the app from the given apkmirror url"""
    response = get_scraper().get(url)
    if response.status_code != 200:
        raise FailedToFetch(f"{url}: {response.status_code}")

    bs4 = BeautifulSoup(response.text, "html.parser")
    versions = bs4.find("div", attrs={"class": "listWidget"})

    out: list[Version] = []
    if versions is not None:
        for versionRow in cast(Tag, versions).findChildren("div", recursive=False)[1:]:
            if versionRow is None:
                print(f"{versionRow} is None")
                continue

            version = versionRow.find("span", {"class": "infoSlide-value"})
            if version is None:
                continue

            version = version.string.strip()
            link = f"https://www.apkmirror.com/{versionRow.find('a')['href']}"
            out.append(Version(version=version, link=link))

    return out


def download_apk(variant: Variant, path: str = "big_file.apkm"):
    """Download apk from the variant link"""
    url = variant.link

    response = get_scraper().get(url)

    if response.status_code != 200:
        raise FailedToFetch(url)

    response_body = BeautifulSoup(response.content, "html.parser")

    downloadButton = response_body.find("a", {"class": "downloadButton"})
    if downloadButton is None:
        raise FailedToFindElement("Download button")

    download_page_link = (
        f"https://www.apkmirror.com/{cast(Tag, downloadButton).attrs['href']}"
    )

    download_page = get_scraper().get(download_page_link)
    if response.status_code != 200:
        raise FailedToFetch(download_page_link)

    download_page_body = BeautifulSoup(download_page.content, "html.parser")

    direct_link = download_page_body.find("a", {"rel": "nofollow"})
    if direct_link is None:
        raise FailedToFindElement("download link")

    direct_link_href = cast(Tag, direct_link).attrs["href"]
    direct_link_url = f"https://www.apkmirror.com/{direct_link_href}"
    print(f"Direct link: {direct_link_url}")

    download(
        direct_link_url,
        path,
        use_scraper=True,
        headers={"Referer": download_page_link},
    )


def get_variants(version: Version) -> list[Variant]:
    url = version.link
    variants_page = get_scraper().get(url)
    if variants_page is None:
        raise FailedToFetch(url)

    variants_page_body = BeautifulSoup(variants_page.content, "html.parser")

    variants_table = variants_page_body.find("div", {"class": "table"})
    if variants_table is None:
        raise FailedToFindElement("variants table")

    variants_table_rows = cast(Tag, variants_table).findChildren(
        "div", recursive=False
    )[1:]

    variants: list[Variant] = []
    for variant_row in variants_table_rows:
        cells = variant_row.findChildren(
            "div", {"class": "table-cell"}, recursive=False
        )
        if len(cells) == 0:
            print("Could not find cells")

        is_bundle_tag = variant_row.find("span", {"class": "apkm-badge"})
        is_bundle = False
        if is_bundle_tag is None:
            print("Failed to find apk-badge")
        else:
            is_bundle = is_bundle_tag.string.strip() == "BUNDLE"

        architecture: str = cells[1].string
        link_element = variant_row.find("a", {"class": "accent_color"})
        if link_element is None:
            print("Failed to find the link element")

        link: str = f"https://www.apkmirror.com{link_element.attrs['href']}"
        variants.append(
            Variant(is_bundle=is_bundle, link=link, architecture=architecture)
        )

    print(variants)
    return variants


================================================
FILE: build_variants.py
================================================
from apkmirror import Version
from utils import patch_apk


def build_apks(latest_version: Version):
    # patch
    apk = "big_file_merged.apk"
    patches = "bins/patches.mpp"
    cli = "bins/morphe-cli.jar"

    common_includes = [
        "Enable app downgrading",
        "Hide FAB",
        "Disable chirp font",
        "Add ability to copy media link",
        "Hide Banner",
        "Hide promote button",
        "Hide Community Notes",
        "Delete from database",
        "Customize Navigation Bar items",
        "Remove premium upsell",
        "Control video auto scroll",
        "Force enable translate",
    ]

    common_excludes = []

    patch_apk(
        cli,
        patches,
        apk,
        includes=["Dynamic color"] + common_includes,
        excludes=common_excludes,
        out=f"x-piko-material-you-v{latest_version.version}.apk",
    )

    patch_apk(
        cli,
        patches,
        apk,
        includes=common_includes,
        excludes=["Dynamic color"] + common_excludes,
        out=f"x-piko-v{latest_version.version}.apk",
    )

    patch_apk(
        cli,
        patches,
        apk,
        includes=["Bring back twitter", "Dynamic color"] + common_includes,
        excludes=common_excludes,
        out=f"twitter-piko-material-you-v{latest_version.version}.apk",
    )

    patch_apk(
        cli,
        patches,
        apk,
        includes=["Bring back twitter"] + common_includes,
        excludes=["Dynamic color"] + common_excludes,
        out=f"twitter-piko-v{latest_version.version}.apk",
    )


================================================
FILE: constants.py
================================================
HEADERS = {
    "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",
    "accept-language": "en-GB,en;q=0.9",
    "cache-control": "no-cache",
    "pragma": "no-cache",
    "priority": "u=0, i",
    "sec-ch-ua": '"Not/A)Brand";v="8", "Chromium";v="126"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Windows"',
    "sec-fetch-dest": "document",
    "sec-fetch-mode": "navigate",
    "sec-fetch-site": "none",
    "sec-fetch-user": "?1",
    "upgrade-insecure-requests": "1",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
}


================================================
FILE: download_bins.py
================================================
import re

import requests

from utils import download


def download_release_asset(
    repo: str,
    regex: str,
    out_dir: str,
    filename = None,
    include_prereleases: bool = False,
    version = None,
):
    url = f"https://api.github.com/repos/{repo}/releases"

    response = requests.get(url)
    if response.status_code != 200:
        raise Exception("Failed to fetch github")

    releases = [r for r in response.json() if include_prereleases or not r["prerelease"]]

    if not releases:
        raise Exception(f"No releases found for {repo}")

    if version is not None:
        releases = [r for r in releases if r["tag_name"] == version]

    if not releases:
        raise Exception(f"No release found for version {version}")

    latest_release = releases[0]

    link = None
    for asset in latest_release["assets"]:
        name = asset["name"]
        if re.search(regex, name):
            link = asset["browser_download_url"]
            if filename is None:
                filename = name
            break

    if link is None:
        raise Exception(f"Failed to find asset matching {regex} on release {latest_release['tag_name']}")

    download(link, f"{out_dir.lstrip('/')}/{filename}")

    return latest_release


def download_apkeditor():
    print("Downloading APKEditor")
    download_release_asset("REAndroid/APKEditor", "APKEditor", "bins", "apkeditor.jar")


def download_morphe_cli(include_prereleases: bool = False):
    print("Downloading morphe cli")
    download_release_asset(
        "MorpheApp/morphe-cli",
        r"^morphe-cli.*-all\.jar$",
        "bins",
        "morphe-cli.jar",
        include_prereleases=include_prereleases,
    )


================================================
FILE: flake.nix
================================================
{
  description = "A development environment for twitter-apk with Java";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs { inherit system; };
      in
      {
        devShells.default = pkgs.mkShell {
          packages = with pkgs; [
            jre          # Java Runtime Environment (OpenJDK)
          ];

          shellHook = ''
            echo "Environment loaded!"
            echo "Java: $(java --version | head -n1)"
          '';
        };
      }
    );
}


================================================
FILE: github.py
================================================
import requests
from constants import HEADERS
from dataclasses import dataclass


@dataclass
class Asset:
    browser_download_url: str
    name: str


@dataclass
class GithubRelease:
    tag_name: str
    html_url: str
    assets: list[Asset]


def get_last_build_version(repo_url: str) -> GithubRelease | None:
    url = f"https://api.github.com/repos/{repo_url}/releases/latest"
    response = requests.get(url, headers=HEADERS)

    print(response.status_code)
    if response.status_code == 200:
        release = response.json()

        assets = [
            Asset(
                browser_download_url=asset["browser_download_url"], name=asset["name"]
            )
            for asset in release["assets"]
        ]

        return GithubRelease(
            tag_name=release["tag_name"], html_url=release["html_url"], assets=assets
        )
    elif response.status_code == 404:
        return


================================================
FILE: main.py
================================================
from apkmirror import Version, Variant
from build_variants import build_apks
from download_bins import download_apkeditor, download_morphe_cli, download_release_asset
import github
from utils import panic, merge_apk, publish_release
import apkmirror
import os
import argparse


def get_latest_release(versions: list[Version]) -> Version | None:
    for i in versions:
        if i.version.find("release") >= 0:
            return i


def process(latest_version: Version):
    variants: list[Variant] = apkmirror.get_variants(latest_version)

    download_link: Variant | None = None
    for variant in variants:
        if variant.is_bundle and ("universal" in variant.architecture or "arm64-v8a" in variant.architecture):
            download_link = variant
            break

    if download_link is None:
        raise Exception("Bundle not Found")

    apkmirror.download_apk(download_link)
    if not os.path.exists("big_file.apkm"):
        panic("Failed to download apk")

    download_apkeditor()

    if not os.path.exists("big_file_merged.apk"):
        merge_apk("big_file.apkm")
    else:
        print("apkm is already merged")

    download_morphe_cli(include_prereleases=True)

    print("Downloading patches")
    pikoRelease = download_release_asset(
        "crimera/piko", "^patches.*mpp$", "bins", "patches.mpp", include_prereleases=True
    )

    message: str = f"""
Changelogs:
[piko-{pikoRelease["tag_name"]}]({pikoRelease["html_url"]})
"""

    build_apks(latest_version)

    publish_release(
        latest_version.version,
        [
            f"x-piko-v{latest_version.version}.apk",
            f"x-piko-material-you-v{latest_version.version}.apk",
            f"twitter-piko-v{latest_version.version}.apk",
            f"twitter-piko-material-you-v{latest_version.version}.apk",
        ],
        message,
        latest_version.version
    )


def main():
    # get latest version
    url: str = "https://www.apkmirror.com/apk/x-corp/twitter/"
    repo_url: str = "lluni/twitter-apk"

    versions = apkmirror.get_versions(url)

    latest_version = get_latest_release(versions)
    if latest_version is None:
        raise Exception("Could not find the latest version")

    # only continue if it's a release
    if latest_version.version.find("release") < 0:
        panic("Latest version is not a release version")

    last_build_version: github.GithubRelease | None = github.get_last_build_version(
        repo_url
    )

    if last_build_version is None:
        panic("Failed to fetch the latest build version")
        return

    # Begin stuff
    if last_build_version.tag_name != latest_version.version:
        print(f"New version found: {latest_version.version}")
    else:
        print("No new version found")
        return

    process(latest_version)


def manual(version:str):
    link = f'https://www.apkmirror.com/apk/x-corp/twitter/x-{version.replace(".","-")}-release'
    latest_version = Version(link=link,version=version)
    process(latest_version)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Piko APK')
    # 0 = auto; 1 = manual;
    parser.add_argument('--m', action="store", dest='mode', default=0)
    parser.add_argument('--v', action="store", dest='version', default=0)

    args = parser.parse_args()
    mode = args.mode

    if not mode: # auto
        main()
    else: # manual
        version = args.version
        if not version:
            raise Exception("Version is required.")
        manual(version)


================================================
FILE: pyproject.toml
================================================
[project]
name = "twitter-apk"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "beautifulsoup4>=4.13.4",
    "requests>=2.32.3",
    "cloudscraper>=1.2.71",
]


================================================
FILE: utils.py
================================================
import os
import requests
import subprocess
import sys
from typing import Optional, List
from github import get_last_build_version

_scraper = None

def get_scraper():
    global _scraper
    if _scraper is None:
        import cloudscraper
        _scraper = cloudscraper.create_scraper()
        _scraper.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
        })
    return _scraper


def panic(message: str):
    print(message, file=sys.stderr)
    exit(1)


def send_message(message: str, token: str, chat_id: str, thread_id: str):
    endpoint = f"https://api.telegram.org/bot{token}/sendMessage"

    data = {
        "parse_mode": "Markdown",
        "disable_web_page_preview": "true",
        "text": message,
        "message_thread_id": thread_id,
        "chat_id": chat_id,
    }

    requests.post(endpoint, data=data)


def report_to_telegram():
    tg_token = os.environ["TG_TOKEN"]
    tg_chat_id = os.environ["TG_CHAT_ID"]
    tg_thread_id = os.environ["TG_THREAD_ID"]
    release = get_last_build_version("crimera/twitter-apk")

    if release is None:
        raise Exception("Could not fetch release")

    downloads = [
        f"[{asset.name}]({asset.browser_download_url})" for asset in release.assets
    ]

    message = f"""
[New Update Released !]({release.html_url})

▼ Downloads ▼

{"\n\n".join(downloads)}
"""

    print(message)

    send_message(message, tg_token, tg_chat_id, tg_thread_id)


def download(link, out, headers=None, use_scraper=False):
    dir_name = os.path.dirname(out)
    if dir_name:
        os.makedirs(dir_name, exist_ok=True)

    if os.path.exists(out):
        print(f"{out} already exists skipping download")
        return

    if use_scraper:
        print(f"Downloading with scraper: {link}")

    session = get_scraper() if use_scraper else requests

    # https://www.slingacademy.com/article/python-requests-module-how-to-download-files-from-urls/#Streaming_Large_Files
    with session.get(link, stream=True, headers=headers) as r:
        r.raise_for_status()
        with open(out, "wb") as f:
            for chunk in r.iter_content(chunk_size=8192):
                if chunk:
                    f.write(chunk)


def run_command(command: list[str]):
    cmd = subprocess.run(command, capture_output=True, shell=True)

    try:
        cmd.check_returncode()
    except subprocess.CalledProcessError:
        print(cmd.stdout)
        print(cmd.stderr)
        exit(1)


def merge_apk(path: str):
    subprocess.run(
        ["java", "-jar", "./bins/apkeditor.jar", "m", "-extractNativeLibs", "true", "-i", path]
    ).check_returncode()


def patch_apk(
    cli: str,
    patches: str,
    apk: str,
    includes: list[str] | None = None,
    excludes: list[str] | None = None,
    out: str | None = None,
):
    command = [
        "java",
        "-jar",
        cli,
        "patch",
        "-p",
        patches,
        # use j-hc's keystore so we wouldn't need to reinstall
        "--keystore",
        "ks.keystore",
        "--keystore-entry-password",
        "123456789",
        "--keystore-password",
        "123456789",
        "--signer",
        "jhc",
        "--keystore-entry-alias",
        "jhc",
    ]

    if includes is not None:
        for i in includes:
            command.append("-e")
            command.append(i)

    if excludes is not None:
        for e in excludes:
            command.append("-d")
            command.append(e)

    if out is not None:
        command.append("--out")
        command.append(out)

    command.append(apk)

    subprocess.run(command).check_returncode()


def publish_release(tag: str, files: list[str], message: str, title = ""):
    key = os.environ.get("GITHUB_TOKEN")
    if key is None:
        raise Exception("GITHUB_TOKEN is not set")

    command = ["gh", "release", "create", "--latest", tag, "--notes", message, "--title", title]

    if len(files) == 0:
        raise Exception("Files should have atleast one item")

    for file in files:
        command.append(file)

    subprocess.run(command, env=os.environ.copy()).check_returncode()
Download .txt
gitextract_pj8qm7k7/

├── .envrc
├── .github/
│   └── workflows/
│       ├── build.yaml
│       ├── daily.yaml
│       └── manual.yaml
├── .gitignore
├── README.md
├── apkmirror.py
├── build_variants.py
├── constants.py
├── download_bins.py
├── flake.nix
├── github.py
├── ks.keystore
├── main.py
├── pyproject.toml
└── utils.py
Download .txt
SYMBOL INDEX (30 symbols across 6 files)

FILE: apkmirror.py
  class Version (line 8) | class Version:
  class Variant (line 14) | class Variant:
  class App (line 21) | class App:
  class FailedToFindElement (line 26) | class FailedToFindElement(Exception):
    method __init__ (line 27) | def __init__(self, message=None) -> None:
  class FailedToFetch (line 34) | class FailedToFetch(Exception):
    method __init__ (line 35) | def __init__(self, url=None) -> None:
  function get_versions (line 40) | def get_versions(url: str) -> list[Version]:
  function download_apk (line 67) | def download_apk(variant: Variant, path: str = "big_file.apkm"):
  function get_variants (line 108) | def get_variants(version: Version) -> list[Variant]:

FILE: build_variants.py
  function build_apks (line 5) | def build_apks(latest_version: Version):

FILE: download_bins.py
  function download_release_asset (line 8) | def download_release_asset(
  function download_apkeditor (line 52) | def download_apkeditor():
  function download_morphe_cli (line 57) | def download_morphe_cli(include_prereleases: bool = False):

FILE: github.py
  class Asset (line 7) | class Asset:
  class GithubRelease (line 13) | class GithubRelease:
  function get_last_build_version (line 19) | def get_last_build_version(repo_url: str) -> GithubRelease | None:

FILE: main.py
  function get_latest_release (line 11) | def get_latest_release(versions: list[Version]) -> Version | None:
  function process (line 17) | def process(latest_version: Version):
  function main (line 67) | def main():
  function manual (line 100) | def manual(version:str):

FILE: utils.py
  function get_scraper (line 10) | def get_scraper():
  function panic (line 21) | def panic(message: str):
  function send_message (line 26) | def send_message(message: str, token: str, chat_id: str, thread_id: str):
  function report_to_telegram (line 40) | def report_to_telegram():
  function download (line 66) | def download(link, out, headers=None, use_scraper=False):
  function run_command (line 89) | def run_command(command: list[str]):
  function merge_apk (line 100) | def merge_apk(path: str):
  function patch_apk (line 106) | def patch_apk(
  function publish_release (line 153) | def publish_release(tag: str, files: list[str], message: str, title = ""):
Condensed preview — 16 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (23K chars).
[
  {
    "path": ".envrc",
    "chars": 10,
    "preview": "use flake\n"
  },
  {
    "path": ".github/workflows/build.yaml",
    "chars": 896,
    "preview": "name: Release\r\n\r\non:\r\n  workflow_dispatch:\r\n\r\npermissions:\r\n  contents: write\r\n\r\njobs:\r\n  build:\r\n    runs-on: ubuntu-la"
  },
  {
    "path": ".github/workflows/daily.yaml",
    "chars": 963,
    "preview": "name: Release - Daily\r\n\r\non:\r\n  schedule:\r\n    - cron: '0 0 * * *' # daily at 00:00 UTC\r\n  workflow_dispatch:\r\n\r\npermiss"
  },
  {
    "path": ".github/workflows/manual.yaml",
    "chars": 1014,
    "preview": "name: Release - manual\n\non:\n  workflow_dispatch:\n    inputs:\n      version_input:\n        description: 'Enter the versio"
  },
  {
    "path": ".gitignore",
    "chars": 34,
    "preview": ".venv\n__pycache__\ntest.py\n.direnv\n"
  },
  {
    "path": "README.md",
    "chars": 304,
    "preview": "Apk builds of [piko](https://github.com/crimera/piko) patches\n\n# Credits\n- [revanced](https://github.com/ReVanced)\n- [@R"
  },
  {
    "path": "apkmirror.py",
    "chars": 4502,
    "preview": "from dataclasses import dataclass\nfrom typing import cast\nfrom bs4 import BeautifulSoup, Tag\nfrom utils import download,"
  },
  {
    "path": "build_variants.py",
    "chars": 1566,
    "preview": "from apkmirror import Version\nfrom utils import patch_apk\n\n\ndef build_apks(latest_version: Version):\n    # patch\n    apk"
  },
  {
    "path": "constants.py",
    "chars": 719,
    "preview": "HEADERS = {\n    \"accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q="
  },
  {
    "path": "download_bins.py",
    "chars": 1696,
    "preview": "import re\n\nimport requests\n\nfrom utils import download\n\n\ndef download_release_asset(\n    repo: str,\n    regex: str,\n    "
  },
  {
    "path": "flake.nix",
    "chars": 684,
    "preview": "{\n  description = \"A development environment for twitter-apk with Java\";\n\n  inputs = {\n    nixpkgs.url = \"github:NixOS/n"
  },
  {
    "path": "github.py",
    "chars": 908,
    "preview": "import requests\nfrom constants import HEADERS\nfrom dataclasses import dataclass\n\n\n@dataclass\nclass Asset:\n    browser_do"
  },
  {
    "path": "main.py",
    "chars": 3518,
    "preview": "from apkmirror import Version, Variant\nfrom build_variants import build_apks\nfrom download_bins import download_apkedito"
  },
  {
    "path": "pyproject.toml",
    "chars": 240,
    "preview": "[project]\nname = \"twitter-apk\"\nversion = \"0.1.0\"\ndescription = \"Add your description here\"\nreadme = \"README.md\"\nrequires"
  },
  {
    "path": "utils.py",
    "chars": 4202,
    "preview": "import os\nimport requests\nimport subprocess\nimport sys\nfrom typing import Optional, List\nfrom github import get_last_bui"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the lluni/twitter-apk GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 16 files (20.8 KB), approximately 5.5k tokens, and a symbol index with 30 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!