трансфер с гитхаба

This commit is contained in:
2026-05-15 04:03:13 +06:00
parent e413b50f89
commit a6514cc14f
9 changed files with 768 additions and 21 deletions
+117
View File
@@ -0,0 +1,117 @@
import requests
import os
from yandex_music import Client
def get_itunes_search_data(query):
url = "https://itunes.apple.com/search"
params = {"term": query, "entity": "album", "limit": 1}
try:
response = requests.get(url, params=params)
return response.json()
except Exception as e:
print(f"iTunes API Error: {e}")
return None
def extract_itunes_album(data):
if not data or data.get("resultCount") == 0:
return None
return data["results"][0]
def get_itunes_tracks(album_id):
params = {"id": album_id, "entity": "song"}
response = requests.get("https://itunes.apple.com/lookup", params=params)
results = response.json().get("results", [])
return results[1:] if len(results) > 1 else []
def format_itunes_track(item, artist_name):
ms = item.get('trackTimeMillis', 0)
duration = f"{ms // 60000}:{(ms // 1000) % 60:02d}"
return {
"no": item.get("trackNumber"),
"artist": artist_name,
"title": item.get("trackName"),
"duration": duration
}
def get_yandex_client():
try:
return Client().init()
except:
return None
def find_yandex_album(client, query):
search = client.search(query, type_='album')
if not search.albums or not search.albums.results:
return None
return search.albums.results[0]
def format_yandex_track(track):
sec = track.duration_ms // 1000
duration = f"{sec // 60}:{sec % 60:02d}"
artists = ", ".join([a.name for a in track.artists])
return {
"no": getattr(track, 'number', 0),
"artist": artists,
"title": track.title,
"duration": duration
}
def process_itunes(query):
data = get_itunes_search_data(query)
album = extract_itunes_album(data)
if not album:
return None
raw_tracks = get_itunes_tracks(album["collectionId"])
artist = album.get("artistName", "Unknown")
return {
"title": album["collectionName"],
"year": album["releaseDate"][:4],
"tracks": [format_itunes_track(t, artist) for t in raw_tracks]
}
def process_yandex(query):
client = get_yandex_client()
if not client: return None
album_info = find_yandex_album(client, query)
if not album_info: return None
full_album = client.albums_with_tracks(album_info.id)
tracks = []
for vol in full_album.volumes:
for t in vol:
tracks.append(format_yandex_track(t))
return {
"title": album_info.title,
"year": album_info.year or "Unknown",
"tracks": tracks
}
def save_to_file(album_data):
filename = f"{album_data['title']}.txt"
with open(filename, "w", encoding="utf-8") as f:
for t in album_data['tracks']:
line = f"{t['no']}. {t['artist']} - {t['title']} ({t['duration']})"
print(line)
f.write(f"{t['artist']} {t['title']}\n")
print(f"\nГотово! Сохранено в {filename}")
def main(request):
print(f"Поиск '{request}' в iTunes...")
result = process_itunes(request)
if not result:
print("В iTunes не найдено. Ищем в Яндекс.Музыке...")
result = process_yandex(request)
if result:
print(f"Найдено: {result['title']} ({result['year']})")
save_to_file(result)
else:
print(f"Альбом '{request}' не найден ни в одном источнике.")
+75
View File
@@ -0,0 +1,75 @@
import io
import requests
import os
import time
import json
from yandex_music import Client
from PIL import Image
from mutagen.mp3 import MP3
from mutagen.id3 import ID3, APIC
def get_yandex_cover(query, settings):
try:
client = Client().init()
time.sleep(settings["delay"])
search_result = client.search(query, type_='track')
if search_result.tracks and search_result.tracks.results:
track_obj = search_result.tracks.results[0]
if track_obj.og_image:
return "https://" + track_obj.og_image.replace('%%', '1000x1000')
return None
except:
return None
def get_itunes_cover(query, settings):
url = "https://itunes.apple.com/search"
params = {"term": query, "entity": "song", "limit": 1}
try:
time.sleep(settings["delay"])
response = requests.get(url, params=params, timeout=5)
data = response.json()
if data.get("resultCount", 0) > 0:
return data["results"][0]["artworkUrl100"].replace("100x100bb.jpg", "1000x1000bb.jpg")
return None
except:
return None
def get_best_cover(query, settings):
cover_url = get_itunes_cover(query, settings)
if not cover_url:
cover_url = get_yandex_cover(query, settings)
return cover_url
def set_cover(track_path, request):
with open("settings.json", "r", encoding="utf-8") as file:
settings = json.load(file)
cover_url = get_best_cover(request, settings)
if not cover_url:
return
try:
response = requests.get(cover_url, timeout=10)
img = Image.open(io.BytesIO(response.content)).convert("RGB")
buffer = io.BytesIO()
img.save(buffer, format="JPEG", quality=90)
img_data = buffer.getvalue()
audio = MP3(track_path, ID3=ID3)
if audio.tags is None:
audio.add_tags()
audio.tags.add(
APIC(
encoding=3,
mime='image/jpeg',
type=3,
desc='Cover',
data=img_data
)
)
audio.save()
return True
except Exception as e:
print(f"Ошибка: {e}")
return False
+100
View File
@@ -0,0 +1,100 @@
import requests
import sys
import re
import os
import time
import json
from bs4 import BeautifulSoup
from tqdm import tqdm
def ping():
pages = ["https://rus.hitmotop.com/", "https://eu.hitmo-top.com/"]
for page in pages:
status = requests.get(page)
if status.status_code == 200:
return page
print("Ресурсы не доступны")
sys.exit()
def parse(request, page, settings):
url = page + "search?q=" + request.replace(" ", "%20")
time.sleep(settings["delay"])
content = BeautifulSoup(requests.get(url).text, "html.parser")
return content
def get_artists(content):
return [artists.get_text(strip=True) for artists in content.find_all("div", class_="track__desc")]
def get_titles(content):
return [titles.get_text(strip=True) for titles in content.find_all("div", class_="track__title")]
def get_links(content):
return [links.get("href") for links in content.find_all("a", class_="track__download-btn")]
def get_data_dict(content):
dictionary = {
i: [artist, title, link]
for i, (artist, title, link) in enumerate(zip(get_artists(content), get_titles(content), get_links(content)))
}
return dictionary
def get_url(index, dictionary):
return dictionary[index][2]
def handle():
selected_index = int(input("Скачать трек: "))
return selected_index
def playlist():
return 0
def get_filename(index, dictionary):
filename = f"{dictionary[index][0]} - {dictionary[index][1]}.mp3"
filename = re.sub(r'[*"?<>|:$&()\[\]!/]+', "", filename)
return filename
def get_path_to_file(filename, settings):
os.makedirs(settings["save to"], exist_ok=True)
path_to_file = os.path.join(settings["save to"], filename)
return path_to_file
def print_content(dictionary):
for i in range(len(dictionary)):
print(f"{i}. {dictionary[i][0]} - {dictionary[i][1]}")
return None
def download(url, path_to_file, filename, settings):
time.sleep(settings["delay"])
with requests.get(url, stream=True, headers={"User-Agent": "Mozilla/5.0"}) as r:
r.raise_for_status()
size = int(r.headers.get('content-length', 0))
with open(path_to_file, 'wb') as f, tqdm(total=size, unit='B', unit_scale=True) as pbar:
for chunk in r.iter_content(8192):
pbar.update(f.write(chunk))
print(f"Скачано: {filename}")
def main(request, mode):
try:
with open("settings.json", "r", encoding="utf-8") as file:
settings = json.load(file)
except Exception as e:
print(f"Ошибка открытия файла: {e}")
sys.exit()
page = ping()
content = parse(request, page, settings)
dictionary = get_data_dict(content)
if not dictionary:
print(f"По запросу {request} ничего не найдено.")
return
if mode == "handle":
print_content(dictionary)
index = handle()
else:
index = playlist()
url = get_url(index, dictionary)
filename = get_filename(index, dictionary)
path_to_file = get_path_to_file(filename, settings)
download(url, path_to_file, filename, settings)
return path_to_file
+71
View File
@@ -0,0 +1,71 @@
import json
import sys
import re
import random
from yandex_music import Client
def yandex(html_):
pattern = r"playlist/([\w\.-]+)/(\d+)"
match = re.search(pattern, html_)
if match:
owner = match.group(1)
kind = match.group(2)
else:
sys.exit()
client = Client().init()
try:
playlist = client.users_playlists(kind, owner)
print(f"\nПлейлист: {playlist.title}")
print(f"Всего треков: {playlist.track_count}")
print("-" * 30)
file = open(f"{playlist.title}.txt", "w", encoding="utf-8")
for item in playlist.tracks:
track = item.track
artists = ", ".join([a.name for a in track.artists])
title = track.title
file.write(f"{artists} {title}\n")
print(f"{artists}{title}")
print(f"\n{playlist.title}.txt плейлист сформирован")
file.close()
sys.exit()
except Exception:
print(f"Ошибка при чтении плейлиста: {Exception}")
sys.exit()
def spotify(playlist):
try:
with open(playlist, "r", encoding="utf-8") as f:
data = json.load(f)
except Exception as e:
print(f"Ошибка открытия файла: {e}")
sys.exit()
temp_name = str(random.randint(0, 2**32 -1))[:5]
items = data["data"]["playlistV2"]["content"]["items"]
file = open(f"{temp_name}.txt", "w", encoding="utf-8")
for item in items:
track = item["itemV2"]["data"]
title = track["name"]
artist = track["artists"]["items"][0]["profile"]["name"]
file.write(f"{artist} {title}\n")
print(f"{artist}{title}")
file.close()
print(f"\n{temp_name}.txt плейлист сформирован")
sys.exit()
+53
View File
@@ -0,0 +1,53 @@
import yt_dlp
import os
import json
def download_track(input_):
with open ("settings.json", "r", encoding="utf-8") as data:
settings = json.load(data)
query = f"ytsearch1:{input_}"
if not os.path.exists(settings["save to"]):
os.makedirs(settings["save to"])
ydl_opts = {
"format": "bestaudio/best",
"postprocessors": [{
"key": "FFmpegExtractAudio",
"preferredcodec": "mp3",
"preferredquality": "320",
}],
"proxy": settings["proxy"],
"extractor_args": {
"youtube": {
"player_client": ["android"],
"skip": ["webpage"],
}
},
"nocheckcertificate": True,
"outtmpl": settings["save to"] + "%(title)s.%(ext)s",
"quiet": False,
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info_dict = ydl.extract_info(query, download=True)
if 'entries' in info_dict:
video_info = info_dict['entries'][0]
else:
video_info = info_dict
file_path = ydl.prepare_filename(video_info)
final_path = os.path.splitext(file_path)[0] + ".mp3"
print(f"Скачано: {final_path}")
return final_path
except Exception as e:
print(f"Ошибка при скачивании: {e}")
return False