Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7066787a1a | ||
| b3fd9ae6ae | |||
| 4ae207b71c | |||
| ea83d056d3 | |||
| 8ffa5b4a4d | |||
| c145a69ca9 | |||
| 8360f94644 | |||
| 49c9b0fbcc |
1
APK download.automa.json
Normal file
1
APK download.automa.json
Normal file
File diff suppressed because one or more lines are too long
47
README.md
47
README.md
@@ -1,8 +1,45 @@
|
||||
# FeloStore Scraper
|
||||
# 📦 FeloStore Scraper
|
||||
|
||||
This Repository is the "heart" of FeloStore. Here is where all of the APKs are getting downloaded and put in a seperate repository.
|
||||
**FeloStore Scraper** is the core engine of the FeloStore ecosystem. It automates the process of downloading APK files and uploading them to a separate repository for distribution or archival.
|
||||
|
||||
Here is how you can replicate the "FeloStore Scraper"-Setup:
|
||||
---
|
||||
|
||||
1. Download the [Automa Extension](https://www.automa.site/) for your Browser.
|
||||
2.
|
||||
## 🚀 Features
|
||||
|
||||
- Automates APK downloading via browser automation
|
||||
- Seamless integration with Git hosting platforms
|
||||
- Easily customizable for your own use case
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Getting Started
|
||||
|
||||
Follow these steps to replicate the **FeloStore Scraper** setup:
|
||||
|
||||
### 1. Install Automa
|
||||
|
||||
Download and install the [Automa extension](https://www.automa.site/) for your browser.
|
||||
|
||||
### 2. Import the Automa Workflow
|
||||
|
||||
- Download the latest `*.automa.json` workflow file from the [Releases](https://git.felo.gg/FeloStore/Scraper/releases) tab of this repository.
|
||||
- Import the file into Automa.
|
||||
- Customize it to suit your scraping needs.
|
||||
|
||||
### 3. Set Up APK Upload Script
|
||||
|
||||
- Download the latest `upload_apks_to_gitea.py` script from the [Releases](https://git.felo.gg/FeloStore/Scraper/releases).
|
||||
- Modify it for your preferred Git hosting platform (e.g., GitHub, GitLab, etc.).
|
||||
- Tip: You can use an AI assistant to help with this adaptation.
|
||||
|
||||
### 4. Automate Execution
|
||||
|
||||
- Run Automa in the background 24/7.
|
||||
- Automate the execution of the Python script on your system.
|
||||
- Not sure how? Ask an AI how to set up scheduled tasks based on your OS.
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
Pull requests and suggestions are welcome! Feel free to fork this repo and open a PR.
|
||||
105
upload_apks_to_gitea.py
Normal file
105
upload_apks_to_gitea.py
Normal file
@@ -0,0 +1,105 @@
|
||||
import os
|
||||
import glob
|
||||
import time
|
||||
import requests
|
||||
from datetime import datetime
|
||||
|
||||
# Konfiguration
|
||||
GITEA_URL = "https://git.felo.gg"
|
||||
OWNER = "FeloStore"
|
||||
REPO = "Data"
|
||||
TAG = "latest"
|
||||
TOKEN = "YOUR_GIT_AUTH_TOKEN_HERE"
|
||||
DOWNLOAD_FOLDER = os.path.join(os.environ["USERPROFILE"], "Downloads") # Windows-kompatibel
|
||||
HEADERS = {
|
||||
"Authorization": f"token {TOKEN}"
|
||||
}
|
||||
|
||||
def get_release_id_by_tag():
|
||||
url = f"{GITEA_URL}/api/v1/repos/{OWNER}/{REPO}/releases/tags/{TAG}"
|
||||
response = requests.get(url, headers=HEADERS)
|
||||
if response.status_code == 200:
|
||||
release = response.json()
|
||||
return release["id"]
|
||||
else:
|
||||
print(f"❌ Release with Tag '{TAG}' not found. Status: {response.status_code}")
|
||||
return None
|
||||
|
||||
def get_existing_assets(release_id):
|
||||
url = f"{GITEA_URL}/api/v1/repos/{OWNER}/{REPO}/releases/{release_id}"
|
||||
response = requests.get(url, headers=HEADERS)
|
||||
if response.status_code == 200:
|
||||
release = response.json()
|
||||
return release.get("assets", [])
|
||||
else:
|
||||
print(f"❌ Error. Status: {response.status_code}")
|
||||
return []
|
||||
|
||||
def delete_asset(release_id, asset_id):
|
||||
"""Deletes an Asset with its ID"""
|
||||
url = f"{GITEA_URL}/api/v1/repos/{OWNER}/{REPO}/releases/{release_id}/assets/{asset_id}"
|
||||
response = requests.delete(url, headers=HEADERS)
|
||||
if response.status_code in [200, 204]:
|
||||
print(f"✅ Asset deleted.")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ Error: {response.status_code} {response.text}")
|
||||
return False
|
||||
|
||||
def upload_apk(release_id, file_path):
|
||||
filename = os.path.basename(file_path)
|
||||
|
||||
assets = get_existing_assets(release_id)
|
||||
for asset in assets:
|
||||
if asset["name"] == filename:
|
||||
print(f"🔄 Old Version of {filename} found. Deleting...")
|
||||
if delete_asset(release_id, asset["id"]):
|
||||
time.sleep(1)
|
||||
else:
|
||||
print(f"⚠️ Couldnt delete old version of {filename}, overwriting...")
|
||||
|
||||
print(f"Hochladen: {filename}")
|
||||
url = f"{GITEA_URL}/api/v1/repos/{OWNER}/{REPO}/releases/{release_id}/assets"
|
||||
with open(file_path, "rb") as f:
|
||||
files = {"attachment": (filename, f)}
|
||||
response = requests.post(url, headers=HEADERS, files=files)
|
||||
if response.status_code == 201:
|
||||
print(f"✅ Successfully uploaded: {filename}")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ Error: {response.status_code} {response.text}")
|
||||
return False
|
||||
|
||||
def delete_apk_files(apk_files):
|
||||
print(f"Wait 10 seconds before deleting the files...")
|
||||
time.sleep(10)
|
||||
|
||||
for apk in apk_files:
|
||||
filename = os.path.basename(apk)
|
||||
try:
|
||||
os.remove(apk)
|
||||
print(f"🗑️ APK-File deleted: {filename}")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error: {str(e)}")
|
||||
|
||||
def main():
|
||||
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Starte Scan...")
|
||||
release_id = get_release_id_by_tag()
|
||||
if release_id is None:
|
||||
return
|
||||
|
||||
apk_files = glob.glob(os.path.join(DOWNLOAD_FOLDER, "*.apk"))
|
||||
if not apk_files:
|
||||
print("No .apk Files found.")
|
||||
return
|
||||
|
||||
successfully_uploaded = []
|
||||
for apk in apk_files:
|
||||
if upload_apk(release_id, apk):
|
||||
successfully_uploaded.append(apk)
|
||||
|
||||
if successfully_uploaded:
|
||||
delete_apk_files(successfully_uploaded)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user