Initial commit: skills library

- 70 skills with code and documentation
- Add .gitignore (ignore __pycache__, output/, temp/, venv/)
- Clean up test intermediates and caches
This commit is contained in:
hmo
2026-04-26 19:27:40 +08:00
commit 04db423416
861 changed files with 210414 additions and 0 deletions
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
"""
乐谱下载器主脚本
支持从人人钢琴网等网站下载高质量乐谱
自动识别高清版本并清理低质量文件
"""
import os
import sys
import requests
import argparse
from pathlib import Path
def download_sheet_music(song_name, output_dir=None, quality_threshold=50000):
"""
下载乐谱的主函数
Args:
song_name: 歌曲名称(用于搜索)
output_dir: 输出目录
quality_threshold: 文件大小阈值(字节),小于该值的文件将被删除
"""
if output_dir is None:
output_dir = f"{song_name}_sheet_music"
# 创建输出目录
Path(output_dir).mkdir(exist_ok=True)
# 人人钢琴网的URL模式
base_url = "https://www.everyonepiano.cn"
search_url = f"{base_url}/Music-search/?word={song_name}"
print(f"正在搜索: {song_name}")
print(f"搜索URL: {search_url}")
# 这里需要实现实际的搜索和解析逻辑
# 由于网页结构复杂,建议使用playwright或selenium
# 当前版本提供基础框架
return output_dir
def cleanup_low_quality_files(directory, threshold=50000):
"""
清理低质量的小文件
Args:
directory: 目录路径
threshold: 文件大小阈值(字节)
"""
deleted_count = 0
for file_path in Path(directory).glob("*"):
if file_path.is_file() and file_path.stat().st_size < threshold:
print(
f"删除低质量文件: {file_path.name} ({file_path.stat().st_size} bytes)"
)
file_path.unlink()
deleted_count += 1
print(f"共删除 {deleted_count} 个低质量文件")
return deleted_count
def main():
parser = argparse.ArgumentParser(description="乐谱下载器")
parser.add_argument("song_name", help="歌曲名称")
parser.add_argument("--output", "-o", default=None, help="输出目录")
parser.add_argument(
"--threshold", "-t", type=int, default=50000, help="文件大小阈值(字节)"
)
args = parser.parse_args()
try:
output_dir = download_sheet_music(args.song_name, args.output, args.threshold)
cleanup_low_quality_files(output_dir, args.threshold)
print(f"乐谱已保存到: {output_dir}")
except Exception as e:
print(f"错误: {e}")
sys.exit(1)
if __name__ == "__main__":
main()
@@ -0,0 +1,4 @@
#!/usr/bin/env python3
"""Example script - delete if not needed."""
print("Hello from skill!")
@@ -0,0 +1,126 @@
#!/usr/bin/env python3
"""
LilyPond乐谱模板生成器
生成标准的LilyPond格式乐谱文件
"""
import os
import sys
from pathlib import Path
def create_lilypond_template(song_name, key="c", tempo=90, difficulty="standard"):
"""
创建LilyPond模板
Args:
song_name: 歌曲名称
key: 调性(默认c大调)
tempo: 速度
difficulty: 难度级别("simple""standard"
Returns:
LilyPond代码字符串
"""
template = f'''\\version "2.24.0"
% {song_name} - LilyPond 格式
% 可以使用 LilyPond 软件编译生成专业五线谱
\\header {{
title = "{song_name}"
composer = "Traditional"
tagline = ""
}}
global = {{
\\key {key} \\major
\\time 4/4
\\tempo 4 = {tempo}
}}
% 右手旋律(高音谱号)
upper = \\relative c' {{
\\clef treble
% TODO: 添加旋律
c4 c g g | a a g2 |
f4 f e e | d d c2 |
}}
% 左手伴奏(低音谱号)
'''
if difficulty == "simple":
template += """lower = \\relative c {
\\clef bass
% 简化版:只弹根音
c4 c g g | g2 r2 |
f4 f e e | e2 r2 |
}"""
else:
template += """lower = \\relative c {
\\clef bass
% 标准版:完整和弦
<c e g>4 <c e g> <g b d> <g b d> | <g b d>2 r2 |
<a c f>4 <a c f> <g b e> <g b e> | <g b e>2 r2 |
}"""
template += """
\\score {
\\new PianoStaff <<
\\new Staff = "upper" \\with {
midiInstrument = "acoustic grand"
} { \\global \\upper }
\\new Staff = "lower" \\with {
midiInstrument = "acoustic grand"
} { \\global \\lower }
>>
\\layout { }
\\midi {
\\tempo 4 = tempo
}
}"""
return template
def save_lilypond_file(content, filename):
"""保存LilyPond文件"""
with open(filename, "w", encoding="utf-8") as f:
f.write(content)
print(f"LilyPond文件已保存: {filename}")
def main():
import argparse
parser = argparse.ArgumentParser(description="LilyPond模板生成器")
parser.add_argument("song_name", help="歌曲名称")
parser.add_argument("--key", "-k", default="c", help="调性(默认c")
parser.add_argument("--tempo", "-t", type=int, default=90, help="速度(默认90")
parser.add_argument(
"--difficulty",
"-d",
choices=["simple", "standard"],
default="standard",
help="难度级别",
)
parser.add_argument("--output", "-o", default=None, help="输出文件名")
args = parser.parse_args()
if args.output is None:
args.output = f"{args.song_name.replace(' ', '_')}.ly"
try:
content = create_lilypond_template(
args.song_name, args.key, args.tempo, args.difficulty
)
save_lilypond_file(content, args.output)
except Exception as e:
print(f"错误: {e}")
sys.exit(1)
if __name__ == "__main__":
main()
@@ -0,0 +1,106 @@
#!/usr/bin/env python3
"""
乐谱文件质量检查工具
检查文件大小、格式和完整性
"""
import os
from pathlib import Path
def check_file_quality(file_path, min_size=50000):
"""
检查单个文件的质量
Args:
file_path: 文件路径
min_size: 最小文件大小(字节)
Returns:
dict: 质量检查结果
"""
path = Path(file_path)
if not path.exists():
return {"valid": False, "error": "文件不存在"}
size = path.stat().st_size
suffix = path.suffix.lower()
result = {
"valid": True,
"file": str(path),
"size": size,
"format": suffix,
"quality": "high" if size >= min_size else "low",
}
# 格式检查
if suffix not in [".png", ".jpg", ".jpeg", ".pdf", ".ly"]:
result["valid"] = False
result["error"] = f"不支持的文件格式: {suffix}"
# 大小检查
if size < min_size:
result["warning"] = f"文件较小 ({size} bytes),可能质量较低"
return result
def batch_check_directory(directory, min_size=50000):
"""
批量检查目录中的文件
Args:
directory: 目录路径
min_size: 最小文件大小阈值
Returns:
list: 所有文件的检查结果
"""
results = []
path = Path(directory)
if not path.exists():
return [{"valid": False, "error": f"目录不存在: {directory}"}]
for file_path in path.glob("*"):
if file_path.is_file():
results.append(check_file_quality(file_path, min_size))
return results
def print_report(results):
"""打印质量检查报告"""
total_files = len(results)
valid_files = sum(1 for r in results if r.get("valid", False))
high_quality_files = sum(1 for r in results if r.get("quality") == "high")
print(f"=== 乐谱质量检查报告 ===")
print(f"总文件数: {total_files}")
print(f"有效文件: {valid_files}")
print(f"高质量文件: {high_quality_files}")
print(f"低质量文件: {total_files - high_quality_files}")
print("\n--- 详细信息 ---")
for result in results:
status = "" if result.get("valid", False) else ""
quality = result.get("quality", "unknown")
print(f"{status} {result['file']} ({result['size']} bytes, {quality})")
if "warning" in result:
print(f" ⚠️ {result['warning']}")
if "error" in result:
print(f"{result['error']}")
if __name__ == "__main__":
import sys
if len(sys.argv) != 2:
print("用法: python quality_check.py <目录路径>")
sys.exit(1)
directory = sys.argv[1]
results = batch_check_directory(directory)
print_report(results)