scoredl 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scoredl-0.1.0/PKG-INFO +77 -0
- scoredl-0.1.0/README.md +66 -0
- scoredl-0.1.0/builder.py +50 -0
- scoredl-0.1.0/extractor.py +146 -0
- scoredl-0.1.0/main.py +63 -0
- scoredl-0.1.0/pyproject.toml +22 -0
- scoredl-0.1.0/scoredl.egg-info/PKG-INFO +77 -0
- scoredl-0.1.0/scoredl.egg-info/SOURCES.txt +11 -0
- scoredl-0.1.0/scoredl.egg-info/dependency_links.txt +1 -0
- scoredl-0.1.0/scoredl.egg-info/entry_points.txt +2 -0
- scoredl-0.1.0/scoredl.egg-info/requires.txt +4 -0
- scoredl-0.1.0/scoredl.egg-info/top_level.txt +3 -0
- scoredl-0.1.0/setup.cfg +4 -0
scoredl-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: scoredl
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CLI tool to download and assemble MuseScore sheets into high-quality PDFs
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: playwright>=1.40.0
|
|
8
|
+
Requires-Dist: svglib>=1.5.0
|
|
9
|
+
Requires-Dist: reportlab>=4.0.0
|
|
10
|
+
Requires-Dist: pypdf>=4.0.0
|
|
11
|
+
|
|
12
|
+
# ๐ผ scoredl
|
|
13
|
+
|
|
14
|
+
CLI tool sederhana berbasis Python untuk mengunduh partitur musik dari **MuseScore** dan mengonversinya langsung menjadi satu file PDF utuh berkualitas tinggi (lossless SVG).
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
## Fitur
|
|
20
|
+
|
|
21
|
+
- ๐ Auto-scroll & lazy load handling via Playwright
|
|
22
|
+
- ๐ผ๏ธ Konversi vektor SVG murni langsung ke lembaran PDF (lossless)
|
|
23
|
+
- ๐ท๏ธ Penamaan file otomatis berdasarkan metadata judul lagu
|
|
24
|
+
- ๐ Opsi simpan file SVG mentah ke subfolder terpisah (`--keep-svg`)
|
|
25
|
+
- ๐งน Pembersihan file temporary otomatis setelah proses selesai
|
|
26
|
+
|
|
27
|
+
## Instalasi
|
|
28
|
+
|
|
29
|
+
**Metode 1 โ via PyPI (disarankan)**
|
|
30
|
+
```bash
|
|
31
|
+
pip install scoredl
|
|
32
|
+
playwright install chromium
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Metode 2 โ manual (mode developer)**
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/RyhmnyRin/scoredl.git
|
|
38
|
+
cd scoredl
|
|
39
|
+
python -m venv .venv
|
|
40
|
+
|
|
41
|
+
# Windows PowerShell
|
|
42
|
+
.venv\Scripts\Activate.ps1
|
|
43
|
+
|
|
44
|
+
# Linux/macOS
|
|
45
|
+
source .venv/bin/activate
|
|
46
|
+
|
|
47
|
+
pip install -e .
|
|
48
|
+
playwright install chromium
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Penggunaan
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
scoredl "https://musescore.com/user/xxxx/scores/yyyy"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Tentukan nama file output:
|
|
58
|
+
```bash
|
|
59
|
+
scoredl "https://musescore.com/user/xxxx/scores/yyyy" -o "NamaLagu.pdf"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Simpan juga file SVG mentahnya (tersimpan di `saved_svgs/<Judul Lagu>/`):
|
|
63
|
+
```bash
|
|
64
|
+
scoredl "https://musescore.com/user/xxxx/scores/yyyy" --keep-svg
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Argumen CLI
|
|
68
|
+
|
|
69
|
+
| Argumen | Opsi Panjang | Deskripsi | Wajib |
|
|
70
|
+
|---|---|---|---|
|
|
71
|
+
| `url` | โ | URL partitur MuseScore | โ
|
|
|
72
|
+
| `-o` | `--output` | Nama file PDF output | โ |
|
|
73
|
+
| โ | `--keep-svg` | Simpan file SVG mentah per halaman | โ |
|
|
74
|
+
|
|
75
|
+
## Kontributor
|
|
76
|
+
|
|
77
|
+
- [RyhmnyRin](https://github.com/RyhmnyRin)
|
scoredl-0.1.0/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# ๐ผ scoredl
|
|
2
|
+
|
|
3
|
+
CLI tool sederhana berbasis Python untuk mengunduh partitur musik dari **MuseScore** dan mengonversinya langsung menjadi satu file PDF utuh berkualitas tinggi (lossless SVG).
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## Fitur
|
|
9
|
+
|
|
10
|
+
- ๐ Auto-scroll & lazy load handling via Playwright
|
|
11
|
+
- ๐ผ๏ธ Konversi vektor SVG murni langsung ke lembaran PDF (lossless)
|
|
12
|
+
- ๐ท๏ธ Penamaan file otomatis berdasarkan metadata judul lagu
|
|
13
|
+
- ๐ Opsi simpan file SVG mentah ke subfolder terpisah (`--keep-svg`)
|
|
14
|
+
- ๐งน Pembersihan file temporary otomatis setelah proses selesai
|
|
15
|
+
|
|
16
|
+
## Instalasi
|
|
17
|
+
|
|
18
|
+
**Metode 1 โ via PyPI (disarankan)**
|
|
19
|
+
```bash
|
|
20
|
+
pip install scoredl
|
|
21
|
+
playwright install chromium
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Metode 2 โ manual (mode developer)**
|
|
25
|
+
```bash
|
|
26
|
+
git clone https://github.com/RyhmnyRin/scoredl.git
|
|
27
|
+
cd scoredl
|
|
28
|
+
python -m venv .venv
|
|
29
|
+
|
|
30
|
+
# Windows PowerShell
|
|
31
|
+
.venv\Scripts\Activate.ps1
|
|
32
|
+
|
|
33
|
+
# Linux/macOS
|
|
34
|
+
source .venv/bin/activate
|
|
35
|
+
|
|
36
|
+
pip install -e .
|
|
37
|
+
playwright install chromium
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Penggunaan
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
scoredl "https://musescore.com/user/xxxx/scores/yyyy"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Tentukan nama file output:
|
|
47
|
+
```bash
|
|
48
|
+
scoredl "https://musescore.com/user/xxxx/scores/yyyy" -o "NamaLagu.pdf"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Simpan juga file SVG mentahnya (tersimpan di `saved_svgs/<Judul Lagu>/`):
|
|
52
|
+
```bash
|
|
53
|
+
scoredl "https://musescore.com/user/xxxx/scores/yyyy" --keep-svg
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Argumen CLI
|
|
57
|
+
|
|
58
|
+
| Argumen | Opsi Panjang | Deskripsi | Wajib |
|
|
59
|
+
|---|---|---|---|
|
|
60
|
+
| `url` | โ | URL partitur MuseScore | โ
|
|
|
61
|
+
| `-o` | `--output` | Nama file PDF output | โ |
|
|
62
|
+
| โ | `--keep-svg` | Simpan file SVG mentah per halaman | โ |
|
|
63
|
+
|
|
64
|
+
## Kontributor
|
|
65
|
+
|
|
66
|
+
- [RyhmnyRin](https://github.com/RyhmnyRin)
|
scoredl-0.1.0/builder.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from svglib.svglib import svg2rlg
|
|
3
|
+
from reportlab.graphics import renderPDF
|
|
4
|
+
from pypdf import PdfWriter, PdfReader
|
|
5
|
+
|
|
6
|
+
def compile_svgs_to_pdf(svg_files: list, output_pdf_path: str, title: str = "Sheet Music"):
|
|
7
|
+
print(f"[*] Mengonversi {len(svg_files)} halaman SVG ke PDF...")
|
|
8
|
+
temp_pdf_pages = []
|
|
9
|
+
|
|
10
|
+
# 1. Konversi tiap file SVG menjadi PDF lembaran sementara
|
|
11
|
+
for idx, svg_path in enumerate(svg_files):
|
|
12
|
+
print(f"[*] Memproses lembar {idx + 1}/{len(svg_files)}: {svg_path}")
|
|
13
|
+
drawing = svg2rlg(svg_path)
|
|
14
|
+
page_pdf_path = svg_path.replace(".svg", ".pdf")
|
|
15
|
+
renderPDF.drawToFile(drawing, page_pdf_path)
|
|
16
|
+
temp_pdf_pages.append(page_pdf_path)
|
|
17
|
+
|
|
18
|
+
# 2. Gabungkan lembaran PDF individual ke dalam satu file utuh
|
|
19
|
+
print("[*] Menggabungkan seluruh lembar ke file akhir...")
|
|
20
|
+
writer = PdfWriter()
|
|
21
|
+
|
|
22
|
+
for pdf_page in temp_pdf_pages:
|
|
23
|
+
reader = PdfReader(pdf_page)
|
|
24
|
+
for page in reader.pages:
|
|
25
|
+
writer.add_page(page)
|
|
26
|
+
|
|
27
|
+
# 3. Sematkan Metadata Dokumen (Sesuai ide awal lo buat preserve copyright)
|
|
28
|
+
writer.add_metadata({
|
|
29
|
+
"/Title": title,
|
|
30
|
+
"/Producer": "Score-dl CLI Engine"
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
# Simpan file hasil akhir
|
|
34
|
+
with open(output_pdf_path, "wb") as f_out:
|
|
35
|
+
writer.write(f_out)
|
|
36
|
+
|
|
37
|
+
# 4. Cleanup: Hapus file PDF per-halaman sementara
|
|
38
|
+
for temp_pdf in temp_pdf_pages:
|
|
39
|
+
try:
|
|
40
|
+
os.remove(temp_pdf)
|
|
41
|
+
except Exception:
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
print(f"[โ] Selesai! Partitur utuh berhasil disimpan ke: {output_pdf_path}")
|
|
45
|
+
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
# Test manual builder menggunakan file SVG yang sudah lo extract
|
|
48
|
+
folder = "temp_svgs"
|
|
49
|
+
files = [os.path.join(folder, f"page_{i}.svg") for i in range(6)]
|
|
50
|
+
compile_svgs_to_pdf(files, "Non-Breath-Oblige.pdf", title="Non-Breath Oblige - PinocchioP")
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import random
|
|
3
|
+
import time
|
|
4
|
+
from playwright.sync_api import sync_playwright
|
|
5
|
+
|
|
6
|
+
def extract_score_data(score_url: str, output_dir: str = "temp_svgs"):
|
|
7
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
8
|
+
svg_files = []
|
|
9
|
+
metadata = {
|
|
10
|
+
"title": "Unknown Title",
|
|
11
|
+
"pages": 0
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
user_data_dir = os.path.join(os.getcwd(), ".browser_session")
|
|
15
|
+
|
|
16
|
+
with sync_playwright() as p:
|
|
17
|
+
context = p.chromium.launch_persistent_context(
|
|
18
|
+
user_data_dir=user_data_dir,
|
|
19
|
+
headless=False,
|
|
20
|
+
channel="chrome",
|
|
21
|
+
args=[
|
|
22
|
+
"--disable-blink-features=AutomationControlled",
|
|
23
|
+
"--no-sandbox"
|
|
24
|
+
],
|
|
25
|
+
viewport={"width": 1280, "height": 850}
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
page = context.pages[0] if context.pages else context.new_page()
|
|
29
|
+
|
|
30
|
+
# Intercept dan simpan konten SVG langsung dari memory browser
|
|
31
|
+
seen_svg_urls = set()
|
|
32
|
+
downloaded_files = []
|
|
33
|
+
|
|
34
|
+
def handle_response(response):
|
|
35
|
+
url = response.url
|
|
36
|
+
if "scoredata" in url and ".svg" in url:
|
|
37
|
+
if url in seen_svg_urls:
|
|
38
|
+
return
|
|
39
|
+
seen_svg_urls.add(url)
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
svg_content = response.body()
|
|
43
|
+
# Beri nama unik sementara berdasarkan index URL yang ditemukan
|
|
44
|
+
idx = len(seen_svg_urls) - 1
|
|
45
|
+
file_path = os.path.join(output_dir, f"page_{idx}.svg")
|
|
46
|
+
|
|
47
|
+
with open(file_path, "wb") as f:
|
|
48
|
+
f.write(svg_content)
|
|
49
|
+
|
|
50
|
+
print(f"[+] Berhasil menyimpan lembar -> {file_path}")
|
|
51
|
+
except Exception as e:
|
|
52
|
+
print(f"[!] Gagal ekstrak SVG: {e}")
|
|
53
|
+
|
|
54
|
+
page.on("response", handle_response)
|
|
55
|
+
|
|
56
|
+
print(f"[*] Mengakses target: {score_url}")
|
|
57
|
+
page.goto(score_url, wait_until="domcontentloaded", timeout=60000)
|
|
58
|
+
|
|
59
|
+
# Pemeriksaan Cloudflare
|
|
60
|
+
print("[*] Memeriksa proteksi Cloudflare...")
|
|
61
|
+
for _ in range(15):
|
|
62
|
+
title = page.title()
|
|
63
|
+
if "Just a moment" not in title and title.strip() != "":
|
|
64
|
+
break
|
|
65
|
+
time.sleep(1)
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
metadata["title"] = page.title().split("|")[0].strip()
|
|
69
|
+
except Exception:
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
print(f"[*] Judul: {metadata['title']}")
|
|
73
|
+
print("[*] Menunggu elemen lembar partitur...")
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
page.wait_for_selector("#jmuse-scroller-component", timeout=15000)
|
|
77
|
+
time.sleep(2)
|
|
78
|
+
except Exception:
|
|
79
|
+
pass
|
|
80
|
+
|
|
81
|
+
print("[*] Menjalankan human scrolling...")
|
|
82
|
+
|
|
83
|
+
total_height = page.evaluate("""() => {
|
|
84
|
+
const scroller = document.querySelector('#jmuse-scroller-component');
|
|
85
|
+
return scroller ? scroller.scrollHeight : document.body.scrollHeight;
|
|
86
|
+
}""")
|
|
87
|
+
|
|
88
|
+
current_scroll = 0
|
|
89
|
+
step_size = 850
|
|
90
|
+
|
|
91
|
+
while current_scroll < total_height:
|
|
92
|
+
current_scroll += step_size
|
|
93
|
+
|
|
94
|
+
page.evaluate(f"""(scrollVal) => {{
|
|
95
|
+
const scroller = document.querySelector('#jmuse-scroller-component');
|
|
96
|
+
if (scroller) {{
|
|
97
|
+
scroller.scrollTo({{
|
|
98
|
+
top: scrollVal,
|
|
99
|
+
behavior: 'smooth'
|
|
100
|
+
}});
|
|
101
|
+
}} else {{
|
|
102
|
+
window.scrollTo({{
|
|
103
|
+
top: scrollVal,
|
|
104
|
+
behavior: 'smooth'
|
|
105
|
+
}});
|
|
106
|
+
}}
|
|
107
|
+
}}""", current_scroll)
|
|
108
|
+
|
|
109
|
+
time.sleep(1)
|
|
110
|
+
|
|
111
|
+
total_height = page.evaluate("""() => {
|
|
112
|
+
const scroller = document.querySelector('#jmuse-scroller-component');
|
|
113
|
+
return scroller ? scroller.scrollHeight : document.body.scrollHeight;
|
|
114
|
+
}""")
|
|
115
|
+
|
|
116
|
+
print("[*] Menunggu finalisasi asset...")
|
|
117
|
+
time.sleep(0.4)
|
|
118
|
+
|
|
119
|
+
metadata["pages"] = len(svg_files)
|
|
120
|
+
context.close()
|
|
121
|
+
|
|
122
|
+
# Ambil file fisik langsung dari disk agar tidak ada duplikat memori
|
|
123
|
+
all_svgs = [
|
|
124
|
+
os.path.join(output_dir, f)
|
|
125
|
+
for f in os.listdir(output_dir)
|
|
126
|
+
if f.endswith(".svg")
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
# Urutkan berdasarkan angka halaman asli (page_0, page_1, dst)
|
|
130
|
+
import re
|
|
131
|
+
all_svgs.sort(key=lambda x: int(re.search(r'page_(\d+)', x).group(1)))
|
|
132
|
+
|
|
133
|
+
# Update total halaman valid yang sebenarnya tersimpan
|
|
134
|
+
metadata["pages"] = len(all_svgs)
|
|
135
|
+
svg_files = all_svgs
|
|
136
|
+
|
|
137
|
+
return metadata, svg_files
|
|
138
|
+
|
|
139
|
+
if __name__ == "__main__":
|
|
140
|
+
target = "https://musescore.com/user/40260509/scores/7121958"
|
|
141
|
+
meta, files = extract_score_data(target)
|
|
142
|
+
print("\n" + "=" * 40)
|
|
143
|
+
print(f"Hasil Ekstraksi:")
|
|
144
|
+
print(f"Judul : {meta['title']}")
|
|
145
|
+
print(f"Total : {meta['pages']} file SVG tersimpan di folder lokal")
|
|
146
|
+
print("=" * 40)
|
scoredl-0.1.0/main.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
import shutil
|
|
5
|
+
from extractor import extract_score_data
|
|
6
|
+
from builder import compile_svgs_to_pdf
|
|
7
|
+
|
|
8
|
+
def sanitize_filename(name: str) -> str:
|
|
9
|
+
return re.sub(r'[\\/*?:"<>|]', "", name).strip()
|
|
10
|
+
|
|
11
|
+
def main():
|
|
12
|
+
parser = argparse.ArgumentParser(
|
|
13
|
+
prog="scoredl",
|
|
14
|
+
description="CLI Tool untuk mengekstrak partitur MuseScore menjadi PDF berkualitas tinggi."
|
|
15
|
+
)
|
|
16
|
+
parser.add_argument("url", type=str, help="URL lembar musik MuseScore target")
|
|
17
|
+
parser.add_argument("-o", "--output", type=str, default=None, help="Nama file PDF output")
|
|
18
|
+
parser.add_argument("--keep-svg", action="store_true", help="Simpan file SVG ke folder tersendiri sesuai judul")
|
|
19
|
+
|
|
20
|
+
args = parser.parse_args()
|
|
21
|
+
|
|
22
|
+
print("=" * 50)
|
|
23
|
+
print(" Score-dl - MuseScore Sheet Extractor ")
|
|
24
|
+
print("=" * 50)
|
|
25
|
+
|
|
26
|
+
# Gunakan folder sementara unik
|
|
27
|
+
temp_dir = ".temp_extract"
|
|
28
|
+
meta, svg_files = extract_score_data(args.url, output_dir=temp_dir)
|
|
29
|
+
|
|
30
|
+
if not svg_files:
|
|
31
|
+
print("[!] Gagal mengekstrak halaman partitur. Proses dibatalkan.")
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
clean_title = sanitize_filename(meta["title"])
|
|
35
|
+
final_pdf_name = args.output if args.output else f"{clean_title}.pdf"
|
|
36
|
+
if not final_pdf_name.endswith(".pdf"):
|
|
37
|
+
final_pdf_name += ".pdf"
|
|
38
|
+
|
|
39
|
+
# Compile ke PDF
|
|
40
|
+
compile_svgs_to_pdf(svg_files, final_pdf_name, title=meta["title"])
|
|
41
|
+
|
|
42
|
+
# Penanganan folder SVG jika user memilih --keep-svg
|
|
43
|
+
if args.keep_svg:
|
|
44
|
+
# Buat folder khusus sesuai judul lagu agar tidak tertukar
|
|
45
|
+
svg_dest_dir = os.path.join("saved_svgs", clean_title)
|
|
46
|
+
os.makedirs(svg_dest_dir, exist_ok=True)
|
|
47
|
+
|
|
48
|
+
for idx, old_path in enumerate(svg_files):
|
|
49
|
+
new_file_name = f"{clean_title}_page_{idx + 1}.svg"
|
|
50
|
+
new_path = os.path.join(svg_dest_dir, new_file_name)
|
|
51
|
+
shutil.copy2(old_path, new_path)
|
|
52
|
+
|
|
53
|
+
print(f"[โ] Salinan SVG resolusi tinggi tersimpan di: {svg_dest_dir}")
|
|
54
|
+
|
|
55
|
+
# Bersihkan folder sementara
|
|
56
|
+
shutil.rmtree(temp_dir, ignore_errors=True)
|
|
57
|
+
|
|
58
|
+
print("\n" + "=" * 50)
|
|
59
|
+
print(f"[โ] SUKSES! Partitur siap cetak: {final_pdf_name}")
|
|
60
|
+
print("=" * 50)
|
|
61
|
+
|
|
62
|
+
if __name__ == "__main__":
|
|
63
|
+
main()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "scoredl"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "CLI tool to download and assemble MuseScore sheets into high-quality PDFs"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"playwright>=1.40.0",
|
|
13
|
+
"svglib>=1.5.0",
|
|
14
|
+
"reportlab>=4.0.0",
|
|
15
|
+
"pypdf>=4.0.0"
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.scripts]
|
|
19
|
+
scoredl = "main:main"
|
|
20
|
+
|
|
21
|
+
[tool.setuptools]
|
|
22
|
+
py-modules = ["main", "extractor", "builder"]
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: scoredl
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CLI tool to download and assemble MuseScore sheets into high-quality PDFs
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: playwright>=1.40.0
|
|
8
|
+
Requires-Dist: svglib>=1.5.0
|
|
9
|
+
Requires-Dist: reportlab>=4.0.0
|
|
10
|
+
Requires-Dist: pypdf>=4.0.0
|
|
11
|
+
|
|
12
|
+
# ๐ผ scoredl
|
|
13
|
+
|
|
14
|
+
CLI tool sederhana berbasis Python untuk mengunduh partitur musik dari **MuseScore** dan mengonversinya langsung menjadi satu file PDF utuh berkualitas tinggi (lossless SVG).
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
## Fitur
|
|
20
|
+
|
|
21
|
+
- ๐ Auto-scroll & lazy load handling via Playwright
|
|
22
|
+
- ๐ผ๏ธ Konversi vektor SVG murni langsung ke lembaran PDF (lossless)
|
|
23
|
+
- ๐ท๏ธ Penamaan file otomatis berdasarkan metadata judul lagu
|
|
24
|
+
- ๐ Opsi simpan file SVG mentah ke subfolder terpisah (`--keep-svg`)
|
|
25
|
+
- ๐งน Pembersihan file temporary otomatis setelah proses selesai
|
|
26
|
+
|
|
27
|
+
## Instalasi
|
|
28
|
+
|
|
29
|
+
**Metode 1 โ via PyPI (disarankan)**
|
|
30
|
+
```bash
|
|
31
|
+
pip install scoredl
|
|
32
|
+
playwright install chromium
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Metode 2 โ manual (mode developer)**
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/RyhmnyRin/scoredl.git
|
|
38
|
+
cd scoredl
|
|
39
|
+
python -m venv .venv
|
|
40
|
+
|
|
41
|
+
# Windows PowerShell
|
|
42
|
+
.venv\Scripts\Activate.ps1
|
|
43
|
+
|
|
44
|
+
# Linux/macOS
|
|
45
|
+
source .venv/bin/activate
|
|
46
|
+
|
|
47
|
+
pip install -e .
|
|
48
|
+
playwright install chromium
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Penggunaan
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
scoredl "https://musescore.com/user/xxxx/scores/yyyy"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Tentukan nama file output:
|
|
58
|
+
```bash
|
|
59
|
+
scoredl "https://musescore.com/user/xxxx/scores/yyyy" -o "NamaLagu.pdf"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Simpan juga file SVG mentahnya (tersimpan di `saved_svgs/<Judul Lagu>/`):
|
|
63
|
+
```bash
|
|
64
|
+
scoredl "https://musescore.com/user/xxxx/scores/yyyy" --keep-svg
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Argumen CLI
|
|
68
|
+
|
|
69
|
+
| Argumen | Opsi Panjang | Deskripsi | Wajib |
|
|
70
|
+
|---|---|---|---|
|
|
71
|
+
| `url` | โ | URL partitur MuseScore | โ
|
|
|
72
|
+
| `-o` | `--output` | Nama file PDF output | โ |
|
|
73
|
+
| โ | `--keep-svg` | Simpan file SVG mentah per halaman | โ |
|
|
74
|
+
|
|
75
|
+
## Kontributor
|
|
76
|
+
|
|
77
|
+
- [RyhmnyRin](https://github.com/RyhmnyRin)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
builder.py
|
|
3
|
+
extractor.py
|
|
4
|
+
main.py
|
|
5
|
+
pyproject.toml
|
|
6
|
+
scoredl.egg-info/PKG-INFO
|
|
7
|
+
scoredl.egg-info/SOURCES.txt
|
|
8
|
+
scoredl.egg-info/dependency_links.txt
|
|
9
|
+
scoredl.egg-info/entry_points.txt
|
|
10
|
+
scoredl.egg-info/requires.txt
|
|
11
|
+
scoredl.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
scoredl-0.1.0/setup.cfg
ADDED