diff --git a/art.txt b/art.txt new file mode 100644 index 0000000..7eb6d6b --- /dev/null +++ b/art.txt @@ -0,0 +1,14 @@ + __ __ __ + / // / ___ _ / / + / _ / / _ `/ / / + /_//_/ \_,_/ /_/ + __ __ + / / ___ _ ___/ / + / _ \/ _ `// _ / + /_//_/\_,_/ \_,_/ + + __ __ ___ + / // / (_-< + \_,_/ /___/ + + diff --git a/debloat.sh b/debloat.sh new file mode 100755 index 0000000..cf2183a --- /dev/null +++ b/debloat.sh @@ -0,0 +1,233 @@ +#!/system/bin/sh +pm uninstall -k --user 0 com.xiaomi.ab +pm uninstall -k --user 0 com.xiaomi.aiasst.service +pm uninstall -k --user 0 com.xiaomi.gamecenter.sdk.service +pm uninstall -k --user 0 com.xiaomi.joyose +pm uninstall -k --user 0 com.xiaomi.mi_connect_service +pm uninstall -k --user 0 com.xiaomi.micloud.sdk +pm uninstall -k --user 0 com.xiaomi.migameservice +pm uninstall -k --user 0 com.xiaomi.miplay_client +pm uninstall -k --user 0 com.xiaomi.mircs +pm uninstall -k --user 0 com.xiaomi.mirror +pm uninstall -k --user 0 com.xiaomi.payment +pm uninstall -k --user 0 com.xiaomi.powerchecker +pm uninstall -k --user 0 com.xiaomi.simactivate.service +pm uninstall -k --user 0 com.milink.service +pm uninstall -k --user 0 com.miui.analytics +pm uninstall -k --user 0 com.miui.audioeffect +pm uninstall -k --user 0 com.miui.audiomonitor +pm uninstall -k --user 0 com.miui.bugreport +pm uninstall -k --user 0 com.miui.cloudbackup +pm uninstall -k --user 0 com.miui.cloudservice +pm uninstall -k --user 0 com.miui.cloudservice.sysbase +pm uninstall -k --user 0 com.miui.contentcatcher +pm uninstall -k --user 0 com.miui.daemon +pm uninstall -k --user 0 com.miui.hybrid +pm uninstall -k --user 0 com.miui.hybrid.accessory +pm uninstall -k --user 0 com.miui.maintenancemode +pm uninstall -k --user 0 com.miui.micloudsync +pm uninstall -k --user 0 com.miui.miservice +pm uninstall -k --user 0 com.miui.nextpay +pm uninstall -k --user 0 com.miui.personalassistant +pm uninstall -k --user 0 com.miui.phrase +pm uninstall -k --user 0 com.miui.smsextra +pm uninstall -k --user 0 com.miui.systemAdSolution +pm uninstall -k --user 0 com.miui.translation.kingsoft +pm uninstall -k --user 0 com.miui.translation.xmcloud +pm uninstall -k --user 0 com.miui.translation.youdao +pm uninstall -k --user 0 com.miui.translationservice +pm uninstall -k --user 0 com.miui.voiceassist +pm uninstall -k --user 0 com.miui.voicetrigger +pm uninstall -k --user 0 com.miui.vsimcore +pm uninstall -k --user 0 com.miui.wmsvc +pm uninstall -k --user 0 com.mobiletools.systemhelper +pm uninstall -k --user 0 com.android.chrome +pm uninstall -k --user 0 com.google.android.apps.youtube.music +pm uninstall -k --user 0 com.linkedin.android +pm uninstall -k --user 0 com.jewelsblast.ivygames.Adventure.free +pm uninstall -k --user 0 com.amazon.mShop.android.shopping +pm uninstall -k --user 0 com.ss.android.ugc.trill +pm uninstall -k --user 0 com.booking +pm uninstall -k --user 0 com.xiaomi.scanner +pm uninstall -k --user 0 com.miui.weather2 +pm uninstall -k --user 0 com.xiaomi.smarthome +pm uninstall -k --user 0 com.miui.android.fashiongallery +pm uninstall -k --user 0 com.crazy.juicer.xm +pm uninstall -k --user 0 com.sukhavati.gotoplaying.bubble.BubbleShooter.mint +pm uninstall -k --user 0 com.netflix.mediaclient +pm uninstall -k --user 0 com.mi.global.bbs +pm uninstall -k --user 0 com.agoda.mobile.consumer +pm uninstall -k --user 0 com.xiaomi.midrop +pm uninstall -k --user 0 com.block.puzzle.game.hippo.mi +pm uninstall -k --user 0 com.duokan.phone.remotecontroller +pm uninstall -k --user 0 com.logame.eliminateintruder3d +pm uninstall -k --user 0 cn.wps.xiaomi.abroad.lite +pm uninstall -k --user 0 com.xiaomi.calendar +pm uninstall -k --user 0 com.nf.snake +pm uninstall -k --user 0 com.google.android.apps.subscriptions.red +pm uninstall -k --user 0 com.google.android.googlequicksearchbox +pm uninstall -k --user 0 com.mintgames.wordtrip +pm uninstall -k --user 0 ctrip.english +pm uninstall -k --user 0 com.google.android.apps.photos +pm uninstall -k --user 0 com.mintgames.triplecrush.tile.fun +pm uninstall -k --user 0 com.miui.cloudservice +pm uninstall -k --user 0 com.amazon.appmanager +pm uninstall -k --user 0 com.mi.global.shop +pm uninstall -k --user 0 com.facebook.katana +pm uninstall -k --user 0 com.shopee.sg +pm uninstall -k --user 0 com.google.android.marvin.talkback +pm uninstall -k --user 0 com.google.android.projection.gearhead +pm uninstall -k --user 0 com.android.egg +pm uninstall -k --user 0 com.google.android.setupwizard +pm uninstall -k --user 0 com.mi.globalminusscreen +pm uninstall -k --user 0 com.longcheertel.midtest +pm uninstall -k --user 0 com.google.android.apps.googleassistant +pm uninstall -k --user 0 com.longcheertel.AutoTest +pm uninstall -k --user 0 com.miui.backup +pm uninstall -k --user 0 com.android.dreams.basic +pm uninstall -k --user 0 com.android.providers.blockednumber +pm uninstall -k --user 0 com.android.bookmarkprovider +pm uninstall -k --user 0 com.xiaomi.barrage +pm uninstall -k --user 0 com.android.calllogbackup +pm uninstall -k --user 0 com.qualcomm.qti.callfeaturessetting +pm uninstall -k --user 0 com.google.android.ims +pm uninstall -k --user 0 com.longcheertel.cit +pm uninstall -k --user 0 com.android.backupconfirm +pm uninstall -k --user 0 com.android.cts.ctsshim +pm uninstall -k --user 0 com.android.cts.priv.ctsshim +pm uninstall -k --user 0 com.android.localtransport +pm uninstall -k --user 0 com.android.ons +pm uninstall -k --user 0 com.android.providers.partnerbookmarks +pm uninstall -k --user 0 com.android.sharedstoragebackup +pm uninstall -k --user 0 com.android.wallpaperbackup +pm uninstall -k --user 0 com.miui.face.overlay.miui +pm uninstall -k --user 0 com.miui.rom +pm uninstall -k --user 0 com.qualcomm.qti.remoteSimlockAuth +pm uninstall -k --user 0 com.qualcomm.timeservice +pm uninstall -k --user 0 com.android.companiondevicemanager +pm uninstall -k --user 0 com.miui.compass +pm uninstall -k --user 0 com.qualcomm.qti.confdialer +pm uninstall -k --user 0 com.qti.confuridialer +pm uninstall -k --user 0 com.google.android.apps.restore +pm uninstall -k --user 0 com.google.android.apps.turbo +pm uninstall -k --user 0 com.qti.qualcomm.deviceinfo +pm uninstall -k --user 0 com.google.android.apps.wellbeing +pm uninstall -k --user 0 com.android.dynsystem +pm uninstall -k --user 0 com.android.emergency +pm uninstall -k --user 0 com.facebook.system +pm uninstall -k --user 0 com.facebook.appmanager +pm uninstall -k --user 0 com.facebook.services +pm uninstall -k --user 0 com.fido.asm +pm uninstall -k --user 0 com.fido.xiaomi.uafclient +pm uninstall -k --user 0 com.goodix.gftest +pm uninstall -k --user 0 com.fingerprints.extension.service +pm uninstall -k --user 0 com.miui.freeform +pm uninstall -k --user 0 com.caf.fmradio +pm uninstall -k --user 0 com.miui.fm +pm uninstall -k --user 0 com.miui.fmservice +pm uninstall -k --user 0 com.xiaomi.glgm +pm uninstall -k --user 0 com.android.internal.systemui.navbar.gestural_narrow_back +pm uninstall -k --user 0 com.android.internal.systemui.navbar.gestural_extra_wide_back +pm uninstall -k --user 0 com.android.internal.systemui.navbar.gestural_wide_back +pm uninstall -k --user 0 com.android.internal.systemui.navbar.gestural +pm uninstall -k --user 0 com.xiaomi.mipicks +pm uninstall -k --user 0 com.goodix.fingerprint +pm uninstall -k --user 0 com.google.android.gm +pm uninstall -k --user 0 com.android.hotwordenrollment.xgoogle +pm uninstall -k --user 0 com.android.hotwordenrollment.okgoogle +pm uninstall -k --user 0 com.google.android.syncadapters.contacts +pm uninstall -k --user 0 com.google.android.gms.location.history +pm uninstall -k --user 0 com.google.android.onetimeinitializer +pm uninstall -k --user 0 com.google.android.partnersetup +pm uninstall -k --user 0 com.google.android.apps.walletnfcrel +pm uninstall -k --user 0 com.mi.healthglobal +pm uninstall -k --user 0 org.ifaa.aidl.manager +pm uninstall -k --user 0 com.android.keychain +pm uninstall -k --user 0 com.google.android.apps.maps +pm uninstall -k --user 0 com.google.android.feedback +pm uninstall -k --user 0 com.miui.mishare.connectivity +pm uninstall -k --user 0 com.miui.videoplayer +pm uninstall -k --user 0 org.mipay.android.manager +pm uninstall -k --user 0 com.miui.face +pm uninstall -k --user 0 com.android.mms.service +pm uninstall -k --user 0 com.miui.msa.global +pm uninstall -k --user 0 com.miui.player +pm uninstall -k --user 0 com.android.internal.systemui.onehanded.gestural +pm uninstall -k --user 0 com.wdstechnology.android.kryten +pm uninstall -k --user 0 android.autoinstalls.config.Xiaomi.qssi +pm uninstall -k --user 0 com.android.dreams.phototable +pm uninstall -k --user 0 com.google.android.printservice.recommendation +pm uninstall -k --user 0 com.android.printspooler +pm uninstall -k --user 0 com.android.provision +pm uninstall -k --user 0 com.qualcomm.qti.qdma +pm uninstall -k --user 0 com.miui.touchassistant +pm uninstall -k --user 0 com.longcheertel.sarauth +pm uninstall -k --user 0 com.fingerprints.sensortesttool +pm uninstall -k --user 0 com.android.stk +pm uninstall -k --user 0 com.tencent.soter.soterserver +pm uninstall -k --user 0 com.google.android.tts +pm uninstall -k --user 0 com.google.mainline.telemetry +pm uninstall -k --user 0 com.android.bips +pm uninstall -k --user 0 com.android.apps.tag +pm uninstall -k --user 0 com.android.providers.userdictionary +pm uninstall -k --user 0 com.android.managedprovisioning +pm uninstall -k --user 0 com.xiaomi.account +pm uninstall -k --user 0 com.xiaomi.xmsfkeeper +pm uninstall -k --user 0 com.miui.yellowpage +pm uninstall -k --user 0 com.google.android.youtube +pm uninstall -k --user 0 com.android.systemui.gesture.line.overlay +pm uninstall -k --user 0 com.qti.diagservices +pm uninstall -k --user 0 com.qti.dpmserviceapp +pm uninstall -k --user 0 com.qualcomm.embms +pm uninstall -k --user 0 com.google.android.configupdater +pm uninstall -k --user 0 com.miui.phone.carriers.overlay.h3g +pm uninstall -k --user 0 com.miui.phone.carriers.overlay.vodafone +pm uninstall -k --user 0 com.qti.xdivert +pm uninstall -k --user 0 com.android.traceur +pm uninstall -k --user 0 com.qti.qualcomm.datastatusnotification +pm uninstall -k --user 0 com.google.android.overlay.modules.permissioncontroller +pm uninstall -k --user 0 com.google.android.overlay.modules.permissioncontroller.forframework +pm uninstall -k --user 0 com.miui.core.internal.services +pm uninstall -k --user 0 com.miui.system +pm uninstall -k --user 0 com.qualcomm.qti.poweroffalarm +pm uninstall -k --user 0 com.qti.service.colorservice +pm uninstall -k --user 0 com.alibaba.aliexpresshd +pm uninstall -k --user 0 com.google.android.apps.tachyon +pm uninstall -k --user 0 com.google.android.apps.docs +pm uninstall -k --user 0 com.google.android.apps.magazines +pm uninstall -k --user 0 com.google.android.apps.podcasts +pm uninstall -k --user 0 com.google.android.videos +pm uninstall -k --user 0 com.amazon.mp3 +pm uninstall -k --user 0 com.zhiliaoapp.musically +pm uninstall -k --user 0 com.kingsgroup.ss.xiaomi +pm uninstall -k --user 0 com.miui.securityadd +pm uninstall -k --user 0 com.miui.securitycore +pm uninstall -k --user 0 com.google.android.overlay.gmsconfig.common +pm uninstall -k --user 0 com.google.android.overlay.gmsconfig.geotz +pm uninstall -k --user 0 com.google.android.overlay.gmsconfig.gsa +pm uninstall -k --user 0 com.google.android.ext.shared +pm uninstall -k --user 0 com.android.smspush +pm uninstall -k --user 0 com.qualcomm.qti.qccauthmgr +pm uninstall -k --user 0 com.android.se +pm uninstall -k --user 0 com.android.proxyhandler +pm uninstall -k --user 0 com.qti.snapdragon.qcdm_ff +pm uninstall -k --user 0 com.qualcomm.qti.ridemodeaudio +pm uninstall -k --user 0 com.qualcomm.qti.xrcb +pm uninstall -k --user 0 com.qualcomm.qti.xrvd.service +pm uninstall -k --user 0 com.mi.globalbrowser +pm uninstall -k --user 0 com.android.providers.downloads.ui +pm uninstall -k --user 0 com.miui.huanji +pm uninstall -k --user 0 com.miui.calculator +pm uninstall -k --user 0 com.android.contacts +pm uninstall -k --user 0 com.miui.compass +pm uninstall -k --user 0 com.mi.health +pm uninstall -k --user 0 com.android.soundrecorder +pm uninstall -k --user 0 com.android.email +pm uninstall -k --user 0 com.android.mms +pm uninstall -k --user 0 com.miui.notes +pm uninstall -k --user 0 com.miui.cleaner +pm uninstall -k --user 0 cn.wps.moffice_eng.xiaomi.lite +pm uninstall -k --user 0 com.google.android.inputmethod.latin +pm uninstall -k --user 0 com.xiaomi.aiasst.vision +pm uninstall -k --user 0 com.microsoft.appmanager +pm uninstall -k --user 0 com.xiaomi.aicr diff --git a/erofs2ext4.py b/erofs2ext4.py new file mode 100755 index 0000000..6779684 --- /dev/null +++ b/erofs2ext4.py @@ -0,0 +1,96 @@ +import os +import subprocess +import shutil +import tempfile +import argparse +import time + +def check_dependencies(): + required_tools = ['erofsfuse', 'fusermount', 'mkfs.ext4'] + missing = [tool for tool in required_tools if shutil.which(tool) is None] + if missing: + raise RuntimeError(f"Missing tools: {', '.join(missing)}. Install erofs-utils, fuse, and e2fsprogs.") + +def is_mounted(mount_point): + result = subprocess.run( + ['findmnt', '-rn', '-T', mount_point], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL + ) + return result.returncode == 0 + +def create_ext4_image(output_image, size_mb): + subprocess.run(['dd', 'if=/dev/zero', f'of={output_image}', 'bs=1M', f'count={size_mb}'], check=True) + subprocess.run(['mkfs.ext4', '-F', output_image], check=True) + +def safe_copy(src, dst): + try: + if os.path.islink(src): + linkto = os.readlink(src) + os.symlink(linkto, dst) + elif os.path.isfile(src): + shutil.copy2(src, dst, follow_symlinks=False) + elif os.path.isdir(src): + shutil.copytree(src, dst, symlinks=True, dirs_exist_ok=True) + except (shutil.Error, OSError) as e: + print(f"Warning: {str(e)} - Skipping {src}") + +def convert_erofs_to_ext4(erofs_image, output_image): + check_dependencies() + + with tempfile.TemporaryDirectory() as temp_dir: + erofs_mount = os.path.join(temp_dir, 'erofs_mount') + extract_dir = os.path.join(temp_dir, 'extracted_data') + os.makedirs(erofs_mount, exist_ok=True) + os.makedirs(extract_dir, exist_ok=True) + + fuse_proc = subprocess.Popen(['erofsfuse', erofs_image, erofs_mount]) + try: + for _ in range(10): + if is_mounted(erofs_mount): + break + time.sleep(1) + else: + raise RuntimeError("EROFS mount timed out") + + for item in os.listdir(erofs_mount): + src = os.path.join(erofs_mount, item) + dst = os.path.join(extract_dir, item) + safe_copy(src, dst) + + finally: + try: + subprocess.run(['fusermount', '-u', erofs_mount], check=True) + except subprocess.CalledProcessError: + pass + fuse_proc.terminate() + fuse_proc.wait() + + data_size = sum(os.path.getsize(os.path.join(dirpath, f)) + for dirpath, _, files in os.walk(extract_dir) + for f in files if os.path.isfile(os.path.join(dirpath, f))) + size_mb = int((data_size / (1024 * 1024) + 10) * 1.2) + + create_ext4_image(output_image, size_mb) + + ext4_mount = os.path.join(temp_dir, 'ext4_mount') + os.makedirs(ext4_mount, exist_ok=True) + subprocess.run(['mount', '-o', 'loop', output_image, ext4_mount], check=True) + try: + subprocess.run(['rm', '-rf', f'{ext4_mount}/*'], check=True) + subprocess.run(['rsync', '-a', '--safe-links', f'{extract_dir}/', ext4_mount], check=True) + finally: + subprocess.run(['umount', ext4_mount], check=True) + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Convert EROFS image to ext4 using erofsfuse') + parser.add_argument('input_erofs', help='Input EROFS image file') + parser.add_argument('output_ext4', help='Output ext4 image file') + args = parser.parse_args() + + try: + convert_erofs_to_ext4(args.input_erofs, args.output_ext4) + print("Completed!") + except Exception as e: + print(f"Error: {str(e)}") + exit(1) diff --git a/fileshare.py b/fileshare.py new file mode 100755 index 0000000..88650e5 --- /dev/null +++ b/fileshare.py @@ -0,0 +1,269 @@ +#!/bin/env python3 +import os +import sys +import argparse +import hashlib +import asyncio +import aiohttp +from aiohttp import web +from tqdm import tqdm +from datetime import datetime +from math import ceil + +# Optimize buffer settings +CHUNK_SIZE = 256 * 1024 # 256KB +MAX_BUFFER = 4 * 1024 * 1024 # 4MB +MIN_CHUNK_SIZE = 32 * 1024 # 32KB + +def format_size(size_bytes): + for unit in ['B', 'KB', 'MB', 'GB', 'TB']: + if size_bytes < 1024: + return f"{size_bytes:.2f} {unit}" + size_bytes /= 1024 + return f"{size_bytes:.2f} PB" + +async def file_handler(request): + file_path = os.path.join(os.getcwd(), request.match_info['filename']) + + if not os.path.exists(file_path): + return web.Response(status=404, text="File not found") + if not os.path.isfile(file_path): + return web.Response(status=403, text="Invalid file type") + + stats = request.app['stats'] + stats['total_requests'] += 1 + file_size = os.path.getsize(file_path) + stats['total_bytes'] += file_size + + headers = { + "Content-Disposition": f'attachment; filename="{os.path.basename(file_path)}"', + "Content-Length": str(file_size) + } + + response = web.StreamResponse( + status=200, + headers=headers, + reason='OK' + ) + response.content_type = 'application/octet-stream' + + await response.prepare(request) + + try: + start_time = datetime.now() + loop = asyncio.get_running_loop() + + # Synchronous file handling with async chunk processing + with open(file_path, 'rb') as f: + chunk_size = CHUNK_SIZE + while True: + chunk = await loop.run_in_executor(None, f.read, chunk_size) + if not chunk: + break + await response.write(chunk) + # Dynamic buffer adjustment + chunk_size = min(MAX_BUFFER, max(MIN_CHUNK_SIZE, chunk_size * 2)) + + duration = (datetime.now() - start_time).total_seconds() + stats['transfer_speeds'].append(file_size / (duration or 0.001)) + + except Exception as e: + stats['transfer_errors'] += 1 + raise + finally: + await response.write_eof() + + return response + +async def stats_handler(request): + stats = request.app['stats'] + avg_speed = sum(stats['transfer_speeds'])/len(stats['transfer_speeds']) if stats['transfer_speeds'] else 0 + return web.json_response({ + "total_requests": stats['total_requests'], + "total_bytes": stats['total_bytes'], + "average_speed": f"{avg_speed/1e6:.2f} MB/s", + "transfer_errors": stats['transfer_errors'] + }) + +def run_server(host='0.0.0.0', port=8080): + app = web.Application() + app['stats'] = { + 'total_requests': 0, + 'total_bytes': 0, + 'transfer_speeds': [], + 'transfer_errors': 0 + } + + app.router.add_get('/{filename}', file_handler) + app.router.add_get('/_stats', stats_handler) + + print(f"šŸ“” Server running at {host}:{port}") + print(f"šŸ“‚ Shared directory: {os.getcwd()}") + web.run_app(app, host=host, port=port) + +async def calculate_sha1(file_path): + loop = asyncio.get_running_loop() + sha1 = hashlib.sha1() + try: + file_size = os.path.getsize(file_path) + with tqdm(total=file_size, unit='B', unit_scale=True, + desc=f"šŸ” {os.path.basename(file_path)[:15]}", leave=False, + bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt}") as pbar: + + def sync_read(): + with open(file_path, 'rb') as f: + while True: + chunk = f.read(CHUNK_SIZE) + if not chunk: + return + sha1.update(chunk) + pbar.update(len(chunk)) + + await loop.run_in_executor(None, sync_read) + + return sha1.hexdigest() + except Exception as e: + raise RuntimeError(f"SHA1 calculation failed: {e}") + +async def check_local_files(hash_list): + valid_files = [] + download_list = [] + + with tqdm(total=len(hash_list), desc="šŸ“‚ Checking local files", + unit="file", bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt}") as pbar: + for expected_hash, filename in hash_list: + if not os.path.exists(filename): + download_list.append((expected_hash, filename)) + pbar.update(1) + continue + + try: + current_hash = await calculate_sha1(filename) + if current_hash == expected_hash: + valid_files.append(filename) + else: + download_list.append((expected_hash, filename)) + await asyncio.to_thread(os.remove, filename) + tqdm.write(f"ā™»ļø {filename[:20]}... - Invalid hash, deleted") + except Exception as e: + download_list.append((expected_hash, filename)) + tqdm.write(f"āš ļø {filename[:20]}... - Error: {str(e)}") + pbar.update(1) + + return download_list, valid_files + +async def download_file(session, base_url, expected_hash, filename, semaphore, timeout, retries=3): + for attempt in range(retries): + async with semaphore: + temp_filename = f"{filename}.downloading" + downloaded = 0 + start_time = datetime.now() + + try: + async with session.get( + f"{base_url}/{filename}", + timeout=aiohttp.ClientTimeout(total=timeout) + ) as response: + if response.status != 200: + tqdm.write(f"āš ļø {filename[:15]}... - HTTP {response.status}") + await asyncio.sleep(2 ** attempt) + continue + + total_size = int(response.headers.get('Content-Length', 0)) + total_fmt = format_size(total_size) + + with tqdm(total=total_size, unit='B', unit_scale=True, + desc=f"ā¬‡ļø {filename[:15]}", leave=False, + bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt} [{rate_fmt}]") as pbar: + try: + loop = asyncio.get_running_loop() + with open(temp_filename, 'wb') as f: + async for chunk in response.content.iter_chunked(MAX_BUFFER): + await loop.run_in_executor(None, f.write, chunk) + downloaded += len(chunk) + pbar.update(len(chunk)) + + await asyncio.to_thread(os.rename, temp_filename, filename) + current_hash = await calculate_sha1(filename) + if current_hash != expected_hash: + raise ValueError(f"Hash mismatch ({current_hash[:8]}..)") + + duration = datetime.now().timestamp() - start_time.timestamp() + speed = downloaded / max(duration, 0.001) + tqdm.write(f"āœ… {filename[:20]}... - {format_size(speed)}/s (Attempt {attempt+1})") + return True + except Exception as e: + raise e + except Exception as e: + if os.path.exists(temp_filename): + await asyncio.to_thread(os.remove, temp_filename) + tqdm.write(f"āŒ {filename[:15]}... - {str(e)} (Attempt {attempt+1})") + await asyncio.sleep(2 ** attempt) + return False + +async def main_client(base_url, hash_file, parallel=None, timeout=3600): + with open(hash_file) as f: + hash_list = [line.strip().split(maxsplit=1) for line in f if line.strip()] + + download_list, valid_files = await check_local_files(hash_list) + + print(f"\nāœ… Valid files: {len(valid_files)}") + print(f"ā¬‡ļø Files to download: {len(download_list)}") + + if not download_list: + print("\nšŸŽ‰ All files are up to date!") + return + + # Dynamic parallelism + if parallel is None: + parallel = min(ceil(len(download_list)/2), 20) + parallel = max(1, min(parallel, 50)) + + semaphore = asyncio.Semaphore(parallel) + async with aiohttp.ClientSession() as session: + tasks = [ + download_file(session, base_url, h, f, semaphore, timeout) + for h, f in download_list + ] + + results = [] + with tqdm(total=len(tasks), desc="šŸš€ Download Progress", + unit="file", bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt}") as pbar: + for future in asyncio.as_completed(tasks): + result = await future + results.append(result) + pbar.update(1) + + success_count = sum(results) + print(f"\nSuccess: {success_count}/{len(results)} ({success_count/len(results):.1%})") + +def parse_args(): + parser = argparse.ArgumentParser(description='File Sharing System') + subparsers = parser.add_subparsers(dest='mode', required=True) + + server_parser = subparsers.add_parser('server', aliases=['s'], help='Start in server mode') + server_parser.add_argument('-b', '--bind', default='0.0.0.0', help='IP address to bind (default: 0.0.0.0)') + server_parser.add_argument('-p', '--port', type=int, default=8080, help='Server port (default: 8080)') + + client_parser = subparsers.add_parser('client', aliases=['c'], help='Start in client mode') + client_parser.add_argument('-u', '--url', required=True, help='Server URL (e.g.: http://10.7.0.2:8080)') + client_parser.add_argument('-p', '--parallel', type=int, default=None, + help='Parallel downloads (default: auto)') + client_parser.add_argument('-t', '--timeout', type=int, default=3600, + help='Download timeout in seconds (default: 3600)') + client_parser.add_argument('hash_list', help='File containing hash list') + + return parser.parse_args() + +if __name__ == '__main__': + args = parse_args() + + if args.mode in ['server', 's']: + run_server(host=args.bind, port=args.port) + elif args.mode in ['client', 'c']: + asyncio.run(main_client( + base_url=args.url, + hash_file=args.hash_list, + parallel=args.parallel, + timeout=args.timeout + )) diff --git a/melt.sh b/melt.sh new file mode 100755 index 0000000..410e062 --- /dev/null +++ b/melt.sh @@ -0,0 +1,42 @@ +#!/bin/bash +if [ ! -d $PWD/android_kernel_xiaomi_marble ]; then + git clone git@github.com:Pzqqt/android_kernel_xiaomi_marble.git +fi + +if [ ! -d $PWD/clang ]; then + aria2c -x 10 -s 10 -j 10 https://github.com/llvm/llvm-project/releases/download/llvmorg-20.1.0/LLVM-20.1.0-Linux-X64.tar.xz -o clang.tar.xz + mkdir clang + tar -xvf clang.tar.xz -C clang + mv clang/*/* clang/ + rm clang.tar.xz +fi + +cd $PWD/android_kernel_xiaomi_marble + +git stash +git stash drop stash@{0} # Find a normal solution +git reset +git fetch; git pull --rebase +rm arch/arm64/configs/stock_gki_defconfig +rm drivers/power/supply/qti_typec_class.c +rm drivers/power/supply/qti_typec_class.h + +rm -rf patches +mkdir patches +curl https://github.com/Pzqqt/android_kernel_xiaomi_marble/compare/melt-rebase...melt-rebase-4LazyGoogle.diff -o patches/4LazyGoogle.diff || exit +curl https://github.com/Pzqqt/android_kernel_xiaomi_marble/compare/melt-rebase-4LazyGoogle...melt-rebase-hyperos.diff -o patches/hyperos.diff || exit + +git apply --check --ignore-space-change --ignore-whitespace < ./patches/4LazyGoogle.diff || exit +git apply --ignore-space-change --ignore-whitespace < ./patches/4LazyGoogle.diff || exit +git apply --check --ignore-space-change --ignore-whitespace < ./patches/hyperos.diff || exit +git apply --ignore-space-change --ignore-whitespace < ./patches/hyperos.diff || exit + +curl https://halhadus.rocks/sharedfiles/other/lxc_support.diff -o patches/lxc_support.diff +git apply --check --ignore-space-change --ignore-whitespace < ./patches/lxc_support.diff || exit +git apply --ignore-space-change --ignore-whitespace < ./patches/lxc_support.diff || exit + +rm -rf out + +export PATH=$PWD/../clang/bin:$PATH +make ARCH=arm64 LLVM=1 LLVM_IAS=1 O=out marble_defconfig +make ARCH=arm64 LLVM=1 LLVM_IAS=1 O=out -j$(nproc --all)